From: Mike Bayer Date: Mon, 21 Feb 2022 21:56:16 +0000 (-0500) Subject: undefer column name sooner to accommodate composites X-Git-Tag: rel_2_0_0b1~475 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35c57486008b865ce06840ea80dd65750afa1849;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git undefer column name sooner to accommodate composites This was from adding composite class introspection as a means of determining column name, cols need to have their normal attribute name set up already. Fixes: #7751 Change-Id: I1fe61c135af9b1bf9bc289f683640e63bcc69045 --- diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py index 342aa772b0..5c72371b29 100644 --- a/lib/sqlalchemy/orm/decl_base.py +++ b/lib/sqlalchemy/orm/decl_base.py @@ -833,6 +833,8 @@ class _ClassScanMapperConfig(_MapperConfig): "for the MetaData instance when using a " "declarative base class." ) + elif isinstance(value, Column): + _undefer_column_name(k, self.column_copies.get(value, value)) elif isinstance(value, _IntrospectsAnnotations): annotation, is_dataclass = self.collected_annotations.get( k, (None, None) @@ -865,7 +867,9 @@ class _ClassScanMapperConfig(_MapperConfig): del our_stuff[key] elif isinstance(c, Column): - _undefer_column_name(key, c) + # undefer previously occurred here, and now occurs earlier. + # ensure every column we get here has been named + assert c.name is not None name_to_prop_key[c.name].add(key) declared_columns.add(c) # if the column is the same name as the key, diff --git a/test/orm/test_composites.py b/test/orm/test_composites.py index f41947b6c8..afa3daf135 100644 --- a/test/orm/test_composites.py +++ b/test/orm/test_composites.py @@ -425,6 +425,48 @@ class PointTest(fixtures.MappedTest, testing.AssertsCompiledSQL): e = Edge() eq_(e.start, None) + def test_no_name_declarative(self, decl_base): + """test #7751""" + + class Point: + def __init__(self, x, y): + self.x = x + self.y = y + + def __composite_values__(self): + return self.x, self.y + + def __repr__(self): + return "Point(x=%r, y=%r)" % (self.x, self.y) + + def __eq__(self, other): + return ( + isinstance(other, Point) + and other.x == self.x + and other.y == self.y + ) + + def __ne__(self, other): + return not self.__eq__(other) + + class Vertex(decl_base): + __tablename__ = "vertices" + + id = Column(Integer, primary_key=True) + x1 = Column(Integer) + y1 = Column(Integer) + x2 = Column(Integer) + y2 = Column(Integer) + + start = composite(Point, x1, y1) + end = composite(Point, x2, y2) + + self.assert_compile( + select(Vertex), + "SELECT vertices.id, vertices.x1, vertices.y1, vertices.x2, " + "vertices.y2 FROM vertices", + ) + class NestedTest(fixtures.MappedTest, testing.AssertsCompiledSQL): @classmethod