diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2023-03-30 14:17:30 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2023-03-30 14:17:30 +0000 |
| commit | 72d2ec57928bdf5649c551bdaa87b7fb0943c2fe (patch) | |
| tree | cd7fc1800048882de9e6b8d55f91c7a1a1bdfca3 | |
| parent | 254d621c33dd18fe5f3b8564e9b017a37ac8e029 (diff) | |
| parent | d998b550a1857bd9f3b2418e0ac1592c4cb70ef9 (diff) | |
| download | sqlalchemy-72d2ec57928bdf5649c551bdaa87b7fb0943c2fe.tar.gz | |
Merge "warn for all unmapped expressions" into main
| -rw-r--r-- | doc/build/changelog/unreleased_20/9537.rst | 12 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/decl_base.py | 9 | ||||
| -rw-r--r-- | test/orm/declarative/test_basic.py | 32 | ||||
| -rw-r--r-- | test/orm/inheritance/test_basic.py | 4 |
4 files changed, 46 insertions, 11 deletions
diff --git a/doc/build/changelog/unreleased_20/9537.rst b/doc/build/changelog/unreleased_20/9537.rst new file mode 100644 index 000000000..9d39d479e --- /dev/null +++ b/doc/build/changelog/unreleased_20/9537.rst @@ -0,0 +1,12 @@ +.. change:: + :tags: bug, orm + :tickets: 9537 + + Expanded the warning emitted when a plain :func:`_sql.column` object is + present in a Declarative mapping to include any arbitrary SQL expression + that is not declared within an appropriate property type such as + :func:`_orm.column_property`, :func:`_orm.deferred`, etc. These attributes + are otherwise not mapped at all and remain unchanged within the class + dictionary. As it seems likely that such an expression is usually not + what's intended, this case now warns for all such otherwise ignored + expressions, rather than just the :func:`_sql.column` case. diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py index d01aad439..6be514276 100644 --- a/lib/sqlalchemy/orm/decl_base.py +++ b/lib/sqlalchemy/orm/decl_base.py @@ -1277,11 +1277,14 @@ class _ClassScanMapperConfig(_MapperConfig): def _warn_for_decl_attributes( self, cls: Type[Any], key: str, c: Any ) -> None: - if isinstance(c, expression.ColumnClause): + if isinstance(c, expression.ColumnElement): util.warn( f"Attribute '{key}' on class {cls} appears to " - "be a non-schema 'sqlalchemy.sql.column()' " - "object; this won't be part of the declarative mapping" + "be a non-schema SQLAlchemy expression " + "object; this won't be part of the declarative mapping. " + "To map arbitrary expressions, use ``column_property()`` " + "or a similar function such as ``deferred()``, " + "``query_expression()`` etc. " ) def _produce_column_copies( diff --git a/test/orm/declarative/test_basic.py b/test/orm/declarative/test_basic.py index 4aca4daa6..2d712c823 100644 --- a/test/orm/declarative/test_basic.py +++ b/test/orm/declarative/test_basic.py @@ -1301,10 +1301,10 @@ class DeclarativeMultiBaseTest( class_mapper(Bar).get_property("some_data").columns[0] is t.c.data ) - def test_lower_case_c_column_warning(self): + def test_non_sql_expression_warning_one(self): with assertions.expect_warnings( r"Attribute 'x' on class <class .*Foo.* appears to be a " - r"non-schema 'sqlalchemy.sql.column\(\)' object; " + r"non-schema SQLAlchemy expression object; " ): class Foo(Base): @@ -1314,13 +1314,14 @@ class DeclarativeMultiBaseTest( x = sa.sql.expression.column(Integer) y = Column(Integer) + def test_non_sql_expression_warning_two(self): class MyMixin: x = sa.sql.expression.column(Integer) y = Column(Integer) with assertions.expect_warnings( r"Attribute 'x' on class <class .*MyMixin.* appears to be a " - r"non-schema 'sqlalchemy.sql.column\(\)' object; " + r"non-schema SQLAlchemy expression object; " ): class Foo2(MyMixin, Base): @@ -1328,9 +1329,10 @@ class DeclarativeMultiBaseTest( id = Column(Integer, primary_key=True) + def test_non_sql_expression_warning_three(self): with assertions.expect_warnings( r"Attribute 'x' on class <class .*Foo3.* appears to be a " - r"non-schema 'sqlalchemy.sql.column\(\)' object; " + r"non-schema SQLAlchemy expression object; " ): class Foo3(Base): @@ -1344,9 +1346,10 @@ class DeclarativeMultiBaseTest( y = Column(Integer) + def test_non_sql_expression_warning_four(self): with assertions.expect_warnings( r"Attribute 'x' on class <class .*Foo4.* appears to be a " - r"non-schema 'sqlalchemy.sql.column\(\)' object; " + r"non-schema SQLAlchemy expression object; " ): class MyMixin2: @@ -1361,6 +1364,25 @@ class DeclarativeMultiBaseTest( id = Column(Integer, primary_key=True) + def test_non_sql_expression_warning_five(self): + + # test for #9537 + with assertions.expect_warnings( + r"Attribute 'x' on class <class .*Foo5.* appears to be a " + r"non-schema SQLAlchemy expression object; ", + r"Attribute 'y' on class <class .*Foo5.* appears to be a " + r"non-schema SQLAlchemy expression object; ", + raise_on_any_unexpected=True, + ): + + class Foo5(Base): + __tablename__ = "foo5" + + id = Column(Integer, primary_key=True) + x = Column("x", String()).collate("some collation") + y = Column("y", Integer) + 5 + z = "im not a sqlalchemy thing" + def test_column_named_twice(self): with expect_warnings( "On class 'Foo', Column object 'x' named directly multiple " diff --git a/test/orm/inheritance/test_basic.py b/test/orm/inheritance/test_basic.py index 99cfdc383..27f1d7052 100644 --- a/test/orm/inheritance/test_basic.py +++ b/test/orm/inheritance/test_basic.py @@ -198,11 +198,9 @@ class PolyExpressionEagerLoad(fixtures.DeclarativeMappedTest): child_id = Column(Integer, ForeignKey("a.id")) child = relationship("A") - p_a = case((discriminator == "a", "a"), else_="b") - __mapper_args__ = { "polymorphic_identity": "a", - "polymorphic_on": p_a, + "polymorphic_on": case((discriminator == "a", "a"), else_="b"), } class B(A): |
