]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug affecting PG 9 whereby index reflection
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 20 May 2011 21:56:29 +0000 (17:56 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 20 May 2011 21:56:29 +0000 (17:56 -0400)
would fail if against a column whose name
had changed.  [ticket:2141].

CHANGES
lib/sqlalchemy/dialects/postgresql/base.py
test/dialect/test_postgresql.py

diff --git a/CHANGES b/CHANGES
index bbf39408aaee7f25b3fc182d6f6678d092967ef1..7f9063a99037dd17ffd980161ab9d5d22c17a36d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -63,6 +63,12 @@ CHANGES
     break an ORM column_property() mapping against
     another column_property().  [ticket:2167].
 
+- postgresql
+
+  - Fixed bug affecting PG 9 whereby index reflection
+    would fail if against a column whose name
+    had changed.  [ticket:2141].
+
 - mssql
   - Fixed bug in MSSQL dialect whereby the aliasing
     applied to a schema-qualified table would leak
index d5e3be1e4b20c0b3afdad522740169d3960e08a7..465bfe0ea42e01a925dfa76924afa45e221a99e9 100644 (file)
@@ -1314,16 +1314,31 @@ class PGDialect(default.DefaultDialect):
     def get_indexes(self, connection, table_name, schema, **kw):
         table_oid = self.get_table_oid(connection, table_name, schema,
                                        info_cache=kw.get('info_cache'))
+
         IDX_SQL = """
-          SELECT c.relname, i.indisunique, i.indexprs, i.indpred,
-            a.attname
-          FROM pg_index i, pg_class c, pg_attribute a
-          WHERE i.indrelid = :table_oid AND i.indexrelid = c.oid
-            AND a.attrelid = i.indexrelid AND i.indisprimary = 'f'
-          ORDER BY c.relname, a.attnum
+          SELECT
+              i.relname as relname,
+              ix.indisunique, ix.indexprs, ix.indpred,
+              a.attname
+          FROM
+              pg_class t 
+                    join pg_index ix on t.oid = ix.indrelid
+                    join pg_class i on i.oid=ix.indexrelid
+                    left outer join 
+                        pg_attribute a 
+                        on t.oid=a.attrelid and a.attnum=ANY(ix.indkey)
+          WHERE
+              t.relkind = 'r'
+              and t.oid = :table_oid
+              and ix.indisprimary = 'f'
+          ORDER BY
+              t.relname,
+              i.relname
         """
+
         t = sql.text(IDX_SQL, typemap={'attname':sqltypes.Unicode})
         c = connection.execute(t, table_oid=table_oid)
+
         index_names = {}
         indexes = []
         sv_idx_name = None
@@ -1349,7 +1364,8 @@ class PGDialect(default.DefaultDialect):
                 indexes.append(index_d)
                 index_names[idx_name] = index_d
             index_d['name'] = idx_name
-            index_d['column_names'].append(col)
+            if col is not None:
+                index_d['column_names'].append(col)
             index_d['unique'] = unique
         return indexes
 
index 118a9eb2718644fac189ba6d276b530bbe716e30..18c4477ac73f69305d493cc1ca13a930e3a2d4e8 100644 (file)
@@ -1421,6 +1421,27 @@ class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             warnings.warn = capture_warnings._orig_showwarning
             m1.drop_all()
 
+    @testing.provide_metadata
+    def test_index_reflection_modified(self):
+        """reflect indexes when a column name has changed - PG 9 
+        does not update the name of the column in the index def.
+        [ticket:2141]
+
+        """
+
+        t1 = Table('t', metadata,
+            Column('id', Integer, primary_key=True),
+            Column('x', Integer)
+        )
+        metadata.create_all()
+        conn = testing.db.connect().execution_options(autocommit=True)
+        conn.execute("CREATE INDEX idx1 ON t (x)")
+        conn.execute("ALTER TABLE t RENAME COLUMN x to y")
+
+        ind = testing.db.dialect.get_indexes(conn, "t", None)
+        eq_(ind, [{'unique': False, 'column_names': [u'y'], 'name': u'idx1'}])
+        conn.close()
+
     @testing.fails_on('postgresql+pypostgresql',
                       'pypostgresql bombs on multiple calls')
     def test_set_isolation_level(self):
@@ -1745,8 +1766,6 @@ class ArrayTest(TestBase, AssertsExecutionResults):
             set([('1', '2', '3'), ('4', '5', '6'), (('4', '5'), ('6', '7'))])
         )
 
-
-
 class TimestampTest(TestBase, AssertsExecutionResults):
     __only_on__ = 'postgresql'