potential glitch in schema calcs for metadata.reflect

Issue #2728 resolved
Mike Bayer repo owner created an issue
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index 3a74cbd..3d59e82 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([% (schema, name)
+                                        for name in available]("%s.%s"))
+            else:
+                available_w_schema = available
+
             current = set(self.tables)

             if only is None:
-                load = [for name in available if name not in current](name)
+                load = [for name, schname in
+                            zip(available, available_w_schema)
+                            if schname not in current](name)
             elif util.callable(only):
-                load = [for name in available
-                    if name not in current and only(name, self)](name)
+                load = [for name, schname in
+                            zip(available, available_w_schema)
+                            if schname not in current and only(name, self)](name)
             else:
                 missing = [for name in only if name not in available](name)
                 if missing:

Comments (3)

  1. Mike Bayer reporter

    the bug is with same-named tables in different schemas:

    from sqlalchemy import *
    
    m = MetaData()
    
    t1 = Table('t', m, Column('id', Integer, primary_key=True))
    
    t2 = Table('t', m,
        Column('id1', ForeignKey('t.id')),
        schema="test_schema"
    )
    
    e = create_engine("postgresql://scott:tiger@localhost/test")
    m.create_all(e)
    try:
        m2 = MetaData()
        m2.reflect(e, schema="test_schema")
    
        m3 = MetaData()
        m3.reflect(e)
        m3.reflect(e, schema="test_schema")
    
        print [t.schema) for t in m2.tables.values()]((t.name,)
        print [t.schema) for t in m3.tables.values()]((t.name,)
    finally:
        m.drop_all(e)
    
  2. Log in to comment