From ec04620f1fe609881ed2ad4a3d5b2fe313f4efa4 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 3 Jun 2013 16:40:59 -0400 Subject: [PATCH] Fixed bug whereby using :meth:`.MetaData.reflect` across a remote schema as well as a local schema could produce wrong results in the case where both schemas had a table of the same name. [ticket:2728] --- doc/build/changelog/changelog_08.rst | 8 ++++++++ doc/build/changelog/changelog_09.rst | 9 +++++++++ lib/sqlalchemy/schema.py | 15 ++++++++++++--- test/engine/test_reflection.py | 24 ++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 7e8e618a4e..ed633ec676 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,14 @@ .. changelog:: :version: 0.8.2 + .. change:: + :tags: bug, sql, reflection + :tickets: 2728 + + Fixed bug whereby using :meth:`.MetaData.reflect` across a remote + schema as well as a local schema could produce wrong results + in the case where both schemas had a table of the same name. + .. change:: :tags: bug, sql :tickets: 2726 diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 3c96821053..08a7e74890 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -6,6 +6,15 @@ .. changelog:: :version: 0.9.0 + .. change:: + :tags: bug, sql, reflection + :tickets: 2728 + + Fixed bug whereby using :meth:`.MetaData.reflect` across a remote + schema as well as a local schema could produce wrong results + in the case where both schemas had a table of the same name. + Also in 0.8.2. + .. change:: :tags: bug, sql :tickets: 2726 diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 3a74cbd59d..3d59e82910 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -2711,13 +2711,22 @@ class MetaData(SchemaItem): bind.dialect.get_view_names(conn, schema) ) + if schema is not None: + available_w_schema = util.OrderedSet(["%s.%s" % (schema, name) + for name in available]) + else: + available_w_schema = available + current = set(self.tables) if only is None: - load = [name for name in available if name not in current] + load = [name for name, schname in + zip(available, available_w_schema) + if schname not in current] elif util.callable(only): - load = [name for name in available - if name not in current and only(name, self)] + load = [name for name, schname in + zip(available, available_w_schema) + if schname not in current and only(name, self)] else: missing = [name for name in only if name not in available] if missing: diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py index a562ef73b5..eefa687284 100644 --- a/test/engine/test_reflection.py +++ b/test/engine/test_reflection.py @@ -1245,6 +1245,30 @@ class SchemaTest(fixtures.TestBase): 'test_schema.email_addresses']) ) + @testing.requires.schemas + @testing.provide_metadata + def test_reflect_all_schemas_default_overlap(self): + t1 = Table('t', self.metadata, + Column('id', Integer, primary_key=True)) + + t2 = Table('t', self.metadata, + Column('id1', sa.ForeignKey('t.id')), + schema="test_schema" + ) + + self.metadata.create_all() + m2 = MetaData() + m2.reflect(testing.db, schema="test_schema") + + m3 = MetaData() + m3.reflect(testing.db) + m3.reflect(testing.db, schema="test_schema") + + eq_( + set((t.name, t.schema) for t in m2.tables.values()), + set((t.name, t.schema) for t in m3.tables.values()) + ) + -- 2.47.3