From 4e3806861b19a00203f95b6ecbe411a4e252d152 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 9 May 2023 11:33:30 -0400 Subject: [PATCH] allow column named twice warning to take effect Fixed issue in :func:`_orm.mapped_column` construct where the correct warning for "column X named directly multiple times" would not be emitted when ORM mapped attributes referred to the same :class:`_schema.Column`, if the :func:`_orm.mapped_column` construct were involved, raising an internal assertion instead. Fixes: #9630 Change-Id: I5d9dfaaa225aefb487c9cd981ba3ad78507bb577 --- doc/build/changelog/unreleased_20/9630.rst | 9 +++++++ lib/sqlalchemy/orm/decl_base.py | 6 ++++- test/orm/declarative/test_basic.py | 29 ++++++++++++++++------ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 doc/build/changelog/unreleased_20/9630.rst diff --git a/doc/build/changelog/unreleased_20/9630.rst b/doc/build/changelog/unreleased_20/9630.rst new file mode 100644 index 0000000000..912cb57958 --- /dev/null +++ b/doc/build/changelog/unreleased_20/9630.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, orm + :tickets: 9630 + + Fixed issue in :func:`_orm.mapped_column` construct where the correct + warning for "column X named directly multiple times" would not be emitted + when ORM mapped attributes referred to the same :class:`_schema.Column`, if + the :func:`_orm.mapped_column` construct were involved, raising an internal + assertion instead. diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py index b7d6dd8cfb..71b93de8f7 100644 --- a/lib/sqlalchemy/orm/decl_base.py +++ b/lib/sqlalchemy/orm/decl_base.py @@ -1646,7 +1646,11 @@ class _ClassScanMapperConfig(_MapperConfig): if not isinstance(c, CompositeProperty): name_to_prop_key[col.name].add(key) declared_columns.add(col) - assert col not in column_ordering + + # we would assert this, however we want the below + # warning to take effect instead. See #9630 + # assert col not in column_ordering + column_ordering[col] = sort_order # if this is a MappedColumn and the attribute key we diff --git a/test/orm/declarative/test_basic.py b/test/orm/declarative/test_basic.py index d0e56819cb..2ccbc19f1a 100644 --- a/test/orm/declarative/test_basic.py +++ b/test/orm/declarative/test_basic.py @@ -1419,20 +1419,35 @@ class DeclarativeMultiBaseTest( x = Column("x", Integer) y = Column("x", Integer) - def test_column_repeated_under_prop(self): + @testing.variation("style", ["old", "new"]) + def test_column_repeated_under_prop(self, style): with expect_warnings( "On class 'Foo', Column object 'x' named directly multiple " "times, only one will be used: x, y, z. Consider using " "orm.synonym instead" ), expect_raises(exc.DuplicateColumnError): + if style.old: - class Foo(Base): - __tablename__ = "foo" + class Foo(Base): + __tablename__ = "foo" - id = Column(Integer, primary_key=True) - x = Column("x", Integer) - y = column_property(x) - z = Column("x", Integer) + id = Column(Integer, primary_key=True) + x = Column("x", Integer) + y = column_property(x) + z = Column("x", Integer) + + elif style.new: + + class Foo(Base): + __tablename__ = "foo" + + id = mapped_column(Integer, primary_key=True) + x = mapped_column("x", Integer) + y = column_property(x) + z = mapped_column("x", Integer) + + else: + style.fail() def test_using_explicit_prop_in_schema_objects(self): class Foo(Base): -- 2.47.3