]> 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:59:08 +0000 (20:59 -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
(cherry picked from commit 45a334e38c1baab34d3195c899cb9ca617fb52a7)

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 54a9b02366b8b726bad99c1d6b3dcd5ea57890e4..1de9f3945576c950a6d04368a34a1ff0927ea837 100644 (file)
@@ -2900,7 +2900,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.
@@ -2908,7 +2907,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 64cdf830c85f7e92a5f3c5ed019c94a184b6f579..0780749e17fba96254add85148032925ed44cbcd 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
@@ -2633,6 +2634,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