Skip to content

Cannot update record with sqlalchemy orm #32

Description

@austinlau

It works with executing raw sql. But it cannot update by updating the object with the following error:
StaleDataError: UPDATE statement on table 'table1' expected to update 1 row(s); 0 were matched.

Do anyone know why? Does sqlalchemy have issue with updating view?

Here is the test code:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, JSON, text
from sqlalchemy import event, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.compiler import compiles

# Use this to make the json column has affinity Text
class TEXTJSON(JSON):
    pass

@compiles(TEXTJSON, 'sqlite')
def bi_c(element, compiler, **kw):
    return "TEXTJSON"

@compiles(TEXTJSON)
def bi_c(element, compiler, **kw):
    return compiler.visit_JSON(element, **kw)


Base = declarative_base()
class Table1(Base):
    __tablename__ = 'table1'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String, nullable=True, index=True)
    data = Column(TEXTJSON, nullable=True)
    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(id={self.id})"


# Create database and load extension
engine = create_engine('sqlite:///:memory:')
@event.listens_for(engine, "connect")
def receive_connect(connection, _):
    connection.enable_load_extension(True)
    connection.execute("SELECT load_extension('sqlite_zstd.dll')")
    connection.enable_load_extension(False)

# Create table and session
Base.metadata.create_all(engine)
make_session = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Insert and confirm record can be added and updated
with make_session() as session:
    session.add(Table1(name="record 1", data={"count": 0}))
    session.commit()

with make_session() as session:
    record = session.query(Table1).first()
    record.data = {"count": 1}
    session.commit()

with make_session() as session:
    record = session.query(Table1).first()
    assert record.data["count"] == 1

# Make zstd
with make_session() as session:
    session.execute(text('''
    SELECT
        zstd_enable_transparent('{"table": "table1", "column": "data", "compression_level": 19, "dict_chooser": "''a''"}')
    '''))

# Assert insert, insert is success.
with make_session() as session:
    session.add(Table1(name="record 2", data={"count": 0}))
    session.commit()
    assert session.query(Table1).count() == 2

# Assert update, update is fail:
with make_session() as session:
    record = session.query(Table1).first()
    record.data = {"count": 2}
    session.commit()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions