kvesteri / sqlalchemy-continuum

Versioning extension for SQLAlchemy.
BSD 3-Clause "New" or "Revised" License
566 stars 128 forks source link

SQLModel Compatibility #271

Open pavja2 opened 2 years ago

pavja2 commented 2 years ago

SQLModel (https://github.com/tiangolo/sqlmodel) is notionally built as a layer on top of SQLAlchemy, so it would be awesome to use SQLAlchemy Continuum to version SQLModel managed databases. However, the basic getting started example throws an error when replacing the SQLAlchemy model with a SQLModel version. I'm not entirely clear on how SQLModel inherits from SQLAlchemy and to what degree compatibility is possible, but if there's some trivial fix to bubble up the missing attributes it would be fantastic.

Tutorial Example, but using SQL Model

from typing import Optional
from sqlalchemy_continuum import make_versioned
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import create_session, configure_mappers
from sqlmodel import SQLModel, Field

make_versioned(user_cls=None)

Base = declarative_base()
class Article(SQLModel, table=True):
    __versioned__ = {}
    __tablename__ = 'article'
    id: Optional[int] = Field(primary_key=True)
    name: Optional[str] = Field(default=None)
    content: Optional[str] = Field(default=None)

configure_mappers()
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
session = create_session(bind=engine, autocommit=False)

article = Article(name=u'Some article', content=u'Some content')
session.add(article)
session.commit()
print(article.versions[0].name)
article.name = u'Updated name'
session.commit()
print(article.versions[1].name)
article.versions[0].revert()
print(article.name)

Error Output

File env/lib/python3.8/site-packages/sqlalchemy_continuum/factory.py", line 11, in __call__
    registry = Base.registry._class_registry
AttributeError: type object 'SQLModel' has no attribute 'registry'

File "db_scratch.py", line 18, in <module>
    configure_mappers()
  File "/env/lib/python3.8/site-packages/sqlalchemy/orm/mapper.py", line 3388, in configure_mappers
    _configure_registries(_all_registries(), cascade=True)
  File "/env/lib/python3.8/site-packages/sqlalchemy/orm/mapper.py", line 3421, in _configure_registries
    Mapper.dispatch._for_class(Mapper).after_configured()
  File "/env/lib/python3.8/site-packages/sqlalchemy/event/attr.py", line 256, in __call__
    fn(*args, **kw)
  File "/env/lib/python3.8/site-packages/sqlalchemy/orm/events.py", line 743, in wrap
    fn(*arg, **kw)
  File "/env/lib/python3.8/site-packages/sqlalchemy_continuum/builder.py", line 22, in check_reentry
    handler(*args, **kwargs)
  File "/env/lib/python3.8/site-packages/sqlalchemy_continuum/builder.py", line 177, in configure_versioned_classes
    self.build_transaction_class()
  File "/env/lib/python3.8/site-packages/sqlalchemy_continuum/builder.py", line 154, in build_transaction_class
    self.manager.create_transaction_model()
  File "/env/lib/python3.8/site-packages/sqlalchemy_continuum/manager.py", line 166, in create_transaction_model
    self.transaction_cls = self.transaction_cls(self)
  File "/env/lib/python3.8/site-packages/sqlalchemy_continuum/factory.py", line 13, in __call__
    registry = Base._decl_class_registry
AttributeError: type object 'SQLModel' has no attribute '_decl_class_registry'
alvarolloret commented 2 months ago

Any updates on this? :)

marksteward commented 2 months ago

Update? I think it's a feature request.

hasansezertasan commented 2 months ago

Yep, the it sounds like a feature request yet totally out of sqlalchemy-continuum's scope.