]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Handle non-string, non column expression in index for deferred attach
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 2 May 2020 00:30:18 +0000 (20:30 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 2 May 2020 00:58:42 +0000 (20:58 -0400)
Fixed issue where an :class:`.Index` that is deferred in being associated
with a table, such as as when it contains a :class:`.Column` that is not
associated with any :class:`.Table` yet,  would fail to attach correctly if
it also contained a non table-oriented expession.

Fixes: #5298
Change-Id: I0111c400f6bd4a9f31bf00a9957816c7a3fac783

doc/build/changelog/unreleased_13/5298.rst [new file with mode: 0644]
lib/sqlalchemy/sql/schema.py
test/sql/test_metadata.py

diff --git a/doc/build/changelog/unreleased_13/5298.rst b/doc/build/changelog/unreleased_13/5298.rst
new file mode 100644 (file)
index 0000000..0b9af12
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, schema
+    :tickets: 5298
+
+    Fixed issue where an :class:`.Index` that is deferred in being associated
+    with a table, such as as when it contains a :class:`.Column` that is not
+    associated with any :class:`.Table` yet,  would fail to attach correctly if
+    it also contained a non table-oriented expession.
+
index eddd62d6595c3ca565a8982dbf0f45b414852fe0..b7ac16b0abae6acb4440c6411e5878ed818b6273 100644 (file)
@@ -2807,7 +2807,6 @@ class ColumnCollectionMixin(object):
         cols_w_table = [c for c in col_objs if isinstance(c.table, Table)]
 
         cols_wo_table = set(col_objs).difference(cols_w_table)
-
         if cols_wo_table:
             # feature #3341 - place event listeners for Column objects
             # such that when all those cols are attached, we autoattach.
@@ -2815,7 +2814,9 @@ class ColumnCollectionMixin(object):
 
             # issue #3411 - don't do the per-column auto-attach if some of the
             # columns are specified as strings.
-            has_string_cols = set(self._pending_colargs).difference(col_objs)
+            has_string_cols = set(
+                c for c in self._pending_colargs if c is not None
+            ).difference(col_objs)
             if not has_string_cols:
 
                 def _col_attached(column, table):
index c57932bede424756a6c1967ac199d1d59d8b44cb..36f308073c14e8ff853b34a22f06a0501993ff8a 100644 (file)
@@ -9,6 +9,7 @@ from sqlalchemy import Boolean
 from sqlalchemy import CheckConstraint
 from sqlalchemy import Column
 from sqlalchemy import ColumnDefault
+from sqlalchemy import desc
 from sqlalchemy import Enum
 from sqlalchemy import event
 from sqlalchemy import exc
@@ -2635,6 +2636,23 @@ class ConstraintTest(fixtures.TestBase):
             idx,
         )
 
+    def test_non_attached_col_plus_string_expr(self):
+        # another one that declarative can lead towards
+        metadata = MetaData()
+
+        t1 = Table("a", metadata, Column("id", Integer))
+
+        c2 = Column("x", Integer)
+
+        # if we do it here, no problem
+        # t1.append_column(c2)
+
+        idx = Index("foo", c2, desc("foo"))
+
+        t1.append_column(c2)
+
+        self._assert_index_col_x(t1, idx, columns=True)
+
     def test_column_associated_w_lowercase_table(self):
         from sqlalchemy import table