I have two table classes defined using SqlAlchemy 2.0 syntax. Yesterday, using SqlAlchemy 2.0.21, my application worked fine. This morning, using SqlAlchemy 2.0.22, my application will not start. So why am I creating an issue here instead of SqlAlchemy?
Of the two table classes, one has a generic_relationship defined, while the other does not. Stepping through the code as the application attempts to start, the table class without a generic_relationship is mapped correctly, no issues. The second table class, with a generic_relationship, raises:
TypeError: AttributeImpl.__init__() missing 1 required positional argument: 'dispatch'
The two table classes, along with the definition of the Base declarative class, are shown below:
from sqlalchemy import Boolean, DateTime, ForeignKey
from sqlalchemy.dialects.postgresql import BIGINT, JSONB
from sqlalchemy.ext.mutable import MutableDict
from sqlalchemy.orm import DeclarativeBase, mapped_column, relationship
from sqlalchemy.sql import func
from sqlalchemy.sql.schema import Index
from sqlalchemy.sql.sqltypes import Integer, String, Unicode
from sqlalchemy_utils import generic_relationship
class Base(DeclarativeBase):
pass
class EventCategory(Base):
__tablename__ = "eventcategory"
id = mapped_column(BIGINT, primary_key=True, index=True)
icon_url = mapped_column(
String, nullable=True
)
is_archived = mapped_column(Boolean, default=False)
label = mapped_column(String)
events = relationship("Event", back_populates="category")
class Event(Base):
__tablename__ = "event"
id = mapped_column(BIGINT, primary_key=True, index=True)
action = mapped_column(String)
category_id = mapped_column(BIGINT, ForeignKey("eventcategory.id", ondelete="CASCADE"))
datetime_occurred = mapped_column(DateTime(timezone=True), default=func.now())
is_internal = mapped_column(Boolean, default=False)
object_id = mapped_column(Integer, nullable=True)
object_data = mapped_column(MutableDict.as_mutable(JSONB), default={})
object_type = mapped_column(Unicode)
permalink = mapped_column(String, nullable=True)
source_user_name = mapped_column(String)
text_map_values = mapped_column(MutableDict.as_mutable(JSONB), default={})
category = relationship("EventCategory", back_populates="events")
object = generic_relationship(object_type, object_id)
__table_args__ = (
Index("ix_event_object_data", "object_data", postgresql_using="gin"),
Index("ix_object_event", "object_id", "object_type"),
)
Full traceback:
class Event(Base):
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_api.py", line 847, in __init_subclass__
_as_declarative(cls._sa_registry, cls, cls.__dict__)
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_base.py", line 247, in _as_declarative
return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_base.py", line 328, in setup_mapping
return _ClassScanMapperConfig(
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_base.py", line 582, in __init__
self._early_mapping(mapper_kw)
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_base.py", line 369, in _early_mapping
self.map(mapper_kw)
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/decl_base.py", line 1949, in map
mapper_cls(self.cls, self.local_table, **self.mapper_args),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 2, in __init__
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py", line 851, in __init__
self._configure_properties()
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py", line 1748, in _configure_properties
self._configure_property(
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py", line 2230, in _configure_property
prop.instrument_class(self)
File "/usr/local/lib/python3.11/site-packages/sqlalchemy_utils/generic.py", line 173, in instrument_class
attributes.register_attribute(
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/attributes.py", line 2588, in register_attribute
register_attribute_impl(class_, key, **kw)
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/attributes.py", line 2620, in register_attribute_impl
impl = cast("Type[WriteOnlyAttributeImpl]", impl_class)(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/attributes.py", line 1217, in __init__
super().__init__(*arg, **kw)
TypeError: AttributeImpl.__init__() missing 1 required positional argument: 'dispatch'
I have two table classes defined using SqlAlchemy 2.0 syntax. Yesterday, using SqlAlchemy 2.0.21, my application worked fine. This morning, using SqlAlchemy 2.0.22, my application will not start. So why am I creating an issue here instead of SqlAlchemy?
Of the two table classes, one has a
generic_relationshipdefined, while the other does not. Stepping through the code as the application attempts to start, the table class without ageneric_relationshipis mapped correctly, no issues. The second table class, with ageneric_relationship, raises:TypeError: AttributeImpl.__init__() missing 1 required positional argument: 'dispatch'The two table classes, along with the definition of the
Basedeclarative class, are shown below:Full traceback: