Skip to content

Cannot update record with sqlalchemy orm #32

@austinlau

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()

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