diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-04-10 10:28:44 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-04-10 10:33:09 -0400 |
commit | bf51ff3248d1c87cbc7a846e2e6886339d59b9cb (patch) | |
tree | f00471bbd6e497de058c6064ac2cdd74dd1d8014 | |
parent | 1eb72d9725d0df60206151805c927ad3c6566fb7 (diff) | |
download | sqlalchemy-bf51ff3248d1c87cbc7a846e2e6886339d59b9cb.tar.gz |
include declared_directive as a declared_attr
Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not
correctly honored for subclasses when applied to the ``__mapper_args__``
special method name, as opposed to direct use of
:class:`_orm.declared_attr`. The two constructs should have identical
runtime behaviors.
Fixes: #9625
Change-Id: I0dfe9e73bb45f70dbebc8e94ce280ad3b52e867f
-rw-r--r-- | doc/build/changelog/unreleased_20/9625.rst | 9 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/decl_base.py | 4 | ||||
-rw-r--r-- | test/orm/declarative/test_inheritance.py | 41 |
3 files changed, 52 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_20/9625.rst b/doc/build/changelog/unreleased_20/9625.rst new file mode 100644 index 000000000..edb4c0aa7 --- /dev/null +++ b/doc/build/changelog/unreleased_20/9625.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, orm + :tickets: 9625 + + Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not + correctly honored for subclasses when applied to the ``__mapper_args__`` + special method name, as opposed to direct use of + :class:`_orm.declared_attr`. The two constructs should have identical + runtime behaviors. diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py index bd62c3c1b..beede0ddb 100644 --- a/lib/sqlalchemy/orm/decl_base.py +++ b/lib/sqlalchemy/orm/decl_base.py @@ -260,9 +260,9 @@ def _mapper( @util.preload_module("sqlalchemy.orm.decl_api") def _is_declarative_props(obj: Any) -> bool: - declared_attr = util.preloaded.orm_decl_api.declared_attr + _declared_attr_common = util.preloaded.orm_decl_api._declared_attr_common - return isinstance(obj, (declared_attr, util.classproperty)) + return isinstance(obj, (_declared_attr_common, util.classproperty)) def _check_declared_props_nocascade( diff --git a/test/orm/declarative/test_inheritance.py b/test/orm/declarative/test_inheritance.py index 4cc086be2..e8658926b 100644 --- a/test/orm/declarative/test_inheritance.py +++ b/test/orm/declarative/test_inheritance.py @@ -68,6 +68,47 @@ class DeclarativeInheritanceTest( assert class_mapper(Engineer).polymorphic_identity is None assert class_mapper(Engineer).polymorphic_on is Person.__table__.c.type + @testing.variation("directive", ["declared_attr", "da_directive"]) + def test_declared_attr_mapped_args(self, directive): + class Employee(Base): + __tablename__ = "employee" + + id: Mapped[int] = mapped_column(primary_key=True) + type: Mapped[str] = mapped_column(String(50)) + + if directive.declared_attr: + + @declared_attr + def __mapper_args__(cls): + if cls.__name__ == "Employee": + return { + "polymorphic_on": cls.type, + "polymorphic_identity": "Employee", + } + else: + return {"polymorphic_identity": cls.__name__} + + elif directive.da_directive: + + @declared_attr.directive + def __mapper_args__(cls): + if cls.__name__ == "Employee": + return { + "polymorphic_on": cls.type, + "polymorphic_identity": "Employee", + } + else: + return {"polymorphic_identity": cls.__name__} + + else: + directive.fail() + + class Engineer(Employee): + pass + + eq_(class_mapper(Engineer).polymorphic_identity, "Engineer") + eq_(class_mapper(Employee).polymorphic_identity, "Employee") + def test_we_must_only_copy_column_mapper_args(self): class Person(Base): |