summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-06-14 22:56:21 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-06-14 22:56:21 -0400
commit8f7766cc61479f3c9220c640230eeecd3d49ccc8 (patch)
tree93476645904fd6ae7328b90c727ad2321030db88
parentb1fcd837974a052e46455af99e0a1f18f7074bd8 (diff)
downloadsqlalchemy-8f7766cc61479f3c9220c640230eeecd3d49ccc8.tar.gz
Lookup index columns in parent table by key for copy
Fixed regression in 1.2 due to :ticket:`4147` where a :class:`.Table` that has had some of its indexed columns redefined with new ones, as would occur when overriding columns during reflection or when using :paramref:`.Table.extend_existing`, such that the :meth:`.Table.tometadata` method would fail when attempting to copy those indexes as they still referred to the replaced column. The copy logic now accommodates for this condition. Change-Id: I521aa2c9f3baa0e84598bbdd6ffe4bf07b6e3ba8 Fixes: #4279
-rw-r--r--doc/build/changelog/unreleased_12/4279.rst12
-rw-r--r--lib/sqlalchemy/sql/schema.py3
-rw-r--r--test/sql/test_metadata.py32
3 files changed, 46 insertions, 1 deletions
diff --git a/doc/build/changelog/unreleased_12/4279.rst b/doc/build/changelog/unreleased_12/4279.rst
new file mode 100644
index 000000000..f7cedbf39
--- /dev/null
+++ b/doc/build/changelog/unreleased_12/4279.rst
@@ -0,0 +1,12 @@
+.. change::
+ :tags: bug, sql
+ :tickets: 4279
+
+ Fixed regression in 1.2 due to :ticket:`4147` where a :class:`.Table` that
+ has had some of its indexed columns redefined with new ones, as would occur
+ when overriding columns during reflection or when using
+ :paramref:`.Table.extend_existing`, such that the :meth:`.Table.tometadata`
+ method would fail when attempting to copy those indexes as they still
+ referred to the replaced column. The copy logic now accommodates for this
+ condition.
+
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index 1d6bc4c61..88050b87e 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -69,7 +69,8 @@ def _get_table_key(name, schema):
# break an import cycle
def _copy_expression(expression, source_table, target_table):
def replace(col):
- if source_table.c.contains_column(col):
+ if isinstance(col, Column) and \
+ col.table is source_table and col.key in source_table.c:
return target_table.c[col.key]
else:
return None
diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py
index 7d17e25f3..da133b21a 100644
--- a/test/sql/test_metadata.py
+++ b/test/sql/test_metadata.py
@@ -1066,6 +1066,38 @@ class ToMetaDataTest(fixtures.TestBase, ComparesTables):
sorted([_get_key(i) for i in table_c.indexes])
)
+ def test_indexes_with_col_redefine(self):
+ meta = MetaData()
+
+ table = Table('mytable', meta,
+ Column('id', Integer, primary_key=True),
+ Column('data1', Integer),
+ Column('data2', Integer),
+ Index('text', text('data1 + 1')),
+ )
+ Index('multi', table.c.data1, table.c.data2)
+ Index('func', func.abs(table.c.data1))
+ Index('multi-func', table.c.data1, func.abs(table.c.data2))
+
+ table = Table('mytable', meta,
+ Column('data1', Integer),
+ Column('data2', Integer),
+ extend_existing=True
+ )
+
+ meta2 = MetaData()
+ table_c = table.tometadata(meta2)
+
+ def _get_key(i):
+ return [i.name, i.unique] + \
+ sorted(i.kwargs.items()) + \
+ [str(col) for col in i.expressions]
+
+ eq_(
+ sorted([_get_key(i) for i in table.indexes]),
+ sorted([_get_key(i) for i in table_c.indexes])
+ )
+
@emits_warning("Table '.+' already exists within the given MetaData")
def test_already_exists(self):