sqlalchemy v2.0.36 MappedAsDataclass
sqlalchemy introduced a new check/validation which breaks sqlalchemy-history compability with MappedAsDataclass
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column
from sqlalchemy_history import make_versioned
make_versioned(user_cls="")
class Base(MappedAsDataclass, DeclarativeBase):
pass
class MyModel(Base):
__versioned__ = {}
__tablename__ = "my_model"
id: Mapped[int] = mapped_column(primary_key=True)
_ = MyModel(id=1)
sqlalchemy.exc.InvalidRequestError: Class <class 'sqlalchemy_history.model_builder.MyModelVersion'> already defines a '__table__'. ORM Annotated Dataclasses do not support a pre-existing '__table__' element
upstream refs: https://github.com/sqlalchemy/sqlalchemy/issues/11973 https://github.com/sqlalchemy/sqlalchemy/commit/270b46cef3043d0e675ccb72b1e3a590f835dd4b
Hm, I havent tried MappedAsDataclass yet - do you have any experience or suggestions on how to get this to work ?
PRs are welcome !
Yes, I can confirm this.
Hm, I havent tried
MappedAsDataclassyet - do you have any experience or suggestions on how to get this to work ? PRs are welcome !
Not really, i do not have looked into the sqlalchemy-history internals yet, but maybe i will in the next days
The issue is that sqlalchemy-history tries to build a versioned class based on the model base class (the class inheriting from DeclarativeBase) while using __table__ for the fields. If your base class has MappedAsDataClass it won't accept __table__ with sqlalchemy 2.0.36.
You can mitigate it like this: before:
class Base(DeclarativeBase, MappedAsDataclass):
pass
make_versioned(options={"base_classes": (Base)})
class YourModel(Base): ....
after:
class Base(DeclarativeBase):
pass
class DataclassBase(Base, MappedAsDataclass):
__abstract__ = True
make_versioned(options={"base_classes": (Base)})
class YourModel(DataclassBase): ....