Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update record with sqlalchemy orm #32

Open
austinlau opened this issue Sep 27, 2023 · 0 comments
Open

Cannot update record with sqlalchemy orm #32

austinlau opened this issue Sep 27, 2023 · 0 comments

Comments

@austinlau
Copy link

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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant