corridor / sqlalchemy-history

Library to keep track of changes in SQLAlchemy.
Other
25 stars 24 forks source link

Savepoint not getting released after commit #121

Closed indiVar0508 closed 8 months ago

indiVar0508 commented 9 months ago

savepoint is not getting released after commit.

indiVar0508 commented 8 months ago
from sqlalchemy_history import make_versioned
from sqlalchemy import Column, Integer, Unicode, UnicodeText, create_engine
try:
   from sqlalchemy.orm import declarative_base
except ImportError:  # sqla < 2.x
   from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import create_session, configure_mappers
make_versioned(user_cls=None)
Base = declarative_base()
class Article(Base):
    __versioned__ = {}
    __tablename__ = 'article'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(Unicode(255))
    content = Column(UnicodeText)
configure_mappers()
engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)
session = create_session(bind=engine, autocommit=False)
article = Article(name='Some article', content='Some content')
session.add(article)
session.commit()
nested = session.begin_nested()
# print(article.versions[0].name) # 'Some article'
article.name = 'Updated name'
session.commit()
# print(article.versions[1].name) # 'Updated name'
article.versions[0].revert()
# print(article.name) # 'Some article'

logs:

2024-01-02 18:56:42,625 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2024-01-02 18:56:42,625 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("article")
2024-01-02 18:56:42,625 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,625 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("article")
2024-01-02 18:56:42,625 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("article_version")
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("article_version")
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("transaction")
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("transaction")
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine [raw sql] ()
2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine 
CREATE TABLE article (
        id INTEGER NOT NULL, 
        name VARCHAR(255), 
        content TEXT, 
        PRIMARY KEY (id)
)

2024-01-02 18:56:42,626 INFO sqlalchemy.engine.Engine [no key 0.00008s] ()
2024-01-02 18:56:42,627 INFO sqlalchemy.engine.Engine 
CREATE TABLE article_version (
        id INTEGER NOT NULL, 
        name VARCHAR(255), 
        content TEXT, 
        transaction_id INTEGER NOT NULL, 
        end_transaction_id INTEGER, 
        operation_type SMALLINT NOT NULL, 
        PRIMARY KEY (id, transaction_id)
)

2024-01-02 18:56:42,627 INFO sqlalchemy.engine.Engine [no key 0.00007s] ()
2024-01-02 18:56:42,627 INFO sqlalchemy.engine.Engine CREATE INDEX ix_article_version_operation_type ON article_version (operation_type)
2024-01-02 18:56:42,627 INFO sqlalchemy.engine.Engine [no key 0.00008s] ()
2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine CREATE INDEX ix_article_version_transaction_id ON article_version (transaction_id)
2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine [no key 0.00007s] ()
2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine CREATE INDEX ix_article_version_end_transaction_id ON article_version (end_transaction_id)
2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine [no key 0.00010s] ()
2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine 
CREATE TABLE "transaction" (
        id INTEGER NOT NULL, 
        remote_addr VARCHAR(50), 
        issued_at DATETIME, 
        PRIMARY KEY (id)
)

2024-01-02 18:56:42,628 INFO sqlalchemy.engine.Engine [no key 0.00010s] ()
2024-01-02 18:56:42,629 INFO sqlalchemy.engine.Engine COMMIT
2024-01-02 18:56:42,629 INFO sqlalchemy.engine.Engine BEGIN (implicit)
33
2024-01-02 18:56:42,631 INFO sqlalchemy.engine.Engine INSERT INTO "transaction" (remote_addr, issued_at) VALUES (?, ?)
2024-01-02 18:56:42,631 INFO sqlalchemy.engine.Engine [generated in 0.00023s] (None, '2024-01-02 13:26:42.631432')
33
2024-01-02 18:56:42,633 INFO sqlalchemy.engine.Engine INSERT INTO article (name, content) VALUES (?, ?)
2024-01-02 18:56:42,633 INFO sqlalchemy.engine.Engine [generated in 0.00022s] ('Some article', 'Some content')
2024-01-02 18:56:42,638 INFO sqlalchemy.engine.Engine UPDATE article_version SET end_transaction_id=? WHERE article_version.transaction_id = (SELECT max(article_version_1.transaction_id) AS max_1 
FROM article_version AS article_version_1 
WHERE article_version_1.transaction_id < ? AND article_version_1.id = ?) AND article_version.id = ?
2024-01-02 18:56:42,638 INFO sqlalchemy.engine.Engine [generated in 0.00025s] (1, 1, 1, 1)
33
2024-01-02 18:56:42,639 INFO sqlalchemy.engine.Engine INSERT INTO article_version (id, name, content, transaction_id, end_transaction_id, operation_type) VALUES (?, ?, ?, ?, ?, ?)
2024-01-02 18:56:42,639 INFO sqlalchemy.engine.Engine [generated in 0.00013s] (1, 'Some article', 'Some content', 1, None, 0)
2024-01-02 18:56:42,640 INFO sqlalchemy.engine.Engine COMMIT
user savepoint created
2024-01-02 18:56:42,640 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2024-01-02 18:56:42,640 INFO sqlalchemy.engine.Engine SAVEPOINT sa_savepoint_1
2024-01-02 18:56:42,640 INFO sqlalchemy.engine.Engine [no key 0.00008s] ()
2024-01-02 18:56:42,641 INFO sqlalchemy.engine.Engine SAVEPOINT sa_savepoint_2
2024-01-02 18:56:42,641 INFO sqlalchemy.engine.Engine [no key 0.00008s] ()
33
2024-01-02 18:56:42,641 INFO sqlalchemy.engine.Engine INSERT INTO "transaction" (remote_addr, issued_at) VALUES (?, ?)
2024-01-02 18:56:42,641 INFO sqlalchemy.engine.Engine [cached since 0.01007s ago] (None, '2024-01-02 13:26:42.641349')
33
2024-01-02 18:56:42,642 INFO sqlalchemy.engine.Engine UPDATE article SET name=? WHERE article.id = ?
2024-01-02 18:56:42,642 INFO sqlalchemy.engine.Engine [generated in 0.00022s] ('Updated name', 1)
2024-01-02 18:56:42,647 INFO sqlalchemy.engine.Engine UPDATE article_version SET end_transaction_id=? WHERE article_version.transaction_id = (SELECT max(article_version_1.transaction_id) AS max_1 
FROM article_version AS article_version_1 
WHERE article_version_1.transaction_id < ? AND article_version_1.id = ?) AND article_version.id = ?
2024-01-02 18:56:42,647 INFO sqlalchemy.engine.Engine [cached since 0.008968s ago] (2, 2, 1, 1)
33
2024-01-02 18:56:42,647 INFO sqlalchemy.engine.Engine INSERT INTO article_version (id, name, content, transaction_id, end_transaction_id, operation_type) VALUES (?, ?, ?, ?, ?, ?)
2024-01-02 18:56:42,647 INFO sqlalchemy.engine.Engine [cached since 0.008409s ago] (1, 'Updated name', 'Some content', 2, None, 1)
2024-01-02 18:56:42,648 INFO sqlalchemy.engine.Engine RELEASE SAVEPOINT sa_savepoint_1
2024-01-02 18:56:42,648 INFO sqlalchemy.engine.Engine [no key 0.00014s] ()
temp.py:27: SAWarning: nested transaction already deassociated from connection
  session.commit()
2024-01-02 18:56:42,649 INFO sqlalchemy.engine.Engine COMMIT
2024-01-02 18:56:42,650 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2024-01-02 18:56:42,652 INFO sqlalchemy.engine.Engine SELECT article_version.id AS article_version_id, article_version.name AS article_version_name, article_version.content AS article_version_content, article_version.transaction_id AS article_version_transaction_id, article_version.end_transaction_id AS article_version_end_transaction_id, article_version.operation_type AS article_version_operation_type 
FROM article_version 
WHERE ? = article_version.id ORDER BY article_version.transaction_id
 LIMIT ? OFFSET ?
2024-01-02 18:56:42,652 INFO sqlalchemy.engine.Engine [generated in 0.00038s] (1, 1, 0)
indiVar0508 commented 8 months ago

Fixed in #122