]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Merge pull request #13 from malor/fix_indexes_reflection
authormike bayer <mike_mp@zzzcomputing.com>
Wed, 26 Jun 2013 15:36:02 +0000 (08:36 -0700)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 26 Jun 2013 15:39:29 +0000 (11:39 -0400)
Fix indexes reflection in PostgreSQL

lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/testing/suite/test_reflection.py

index e1fc9e21116f50e97df2434edac8d1eaefdd07c3..ab1327031318f9b820992bf94b501e6b0c48f02d 100644 (file)
@@ -1953,7 +1953,7 @@ class PGDialect(default.DefaultDialect):
           SELECT
               i.relname as relname,
               ix.indisunique, ix.indexprs, ix.indpred,
-              a.attname
+              a.attname, a.attnum, ix.indkey
           FROM
               pg_class t
                     join pg_index ix on t.oid = ix.indrelid
@@ -1973,11 +1973,12 @@ class PGDialect(default.DefaultDialect):
         t = sql.text(IDX_SQL, typemap={'attname': sqltypes.Unicode})
         c = connection.execute(t, table_oid=table_oid)
 
-        index_names = {}
-        indexes = []
+        indexes = defaultdict(lambda: defaultdict(dict))
+
         sv_idx_name = None
         for row in c.fetchall():
-            idx_name, unique, expr, prd, col = row
+            idx_name, unique, expr, prd, col, col_num, idx_key = row
+
             if expr:
                 if idx_name != sv_idx_name:
                     util.warn(
@@ -1986,22 +1987,25 @@ class PGDialect(default.DefaultDialect):
                       % idx_name)
                 sv_idx_name = idx_name
                 continue
+
             if prd and not idx_name == sv_idx_name:
                 util.warn(
                    "Predicate of partial index %s ignored during reflection"
                    % idx_name)
                 sv_idx_name = idx_name
-            if idx_name in index_names:
-                index_d = index_names[idx_name]
-            else:
-                index_d = {'column_names': []}
-                indexes.append(index_d)
-                index_names[idx_name] = index_d
-            index_d['name'] = idx_name
+
+            index = indexes[idx_name]
             if col is not None:
-                index_d['column_names'].append(col)
-            index_d['unique'] = unique
-        return indexes
+                index['cols'][col_num] = col
+            index['key'] = [int(k.strip()) for k in idx_key.split()]
+            index['unique'] = unique
+
+        return [
+            {'name': name,
+             'unique': idx['unique'],
+             'column_names': [idx['cols'][i] for i in idx['key']]}
+            for name, idx in indexes.items()
+        ]
 
     def _load_enums(self, connection):
         if not self.supports_native_enum:
index 7cae485721da8dda5b7be137ff82c4f1cb625536..8524ab66c4f74dfce148c77eb31977c2886956f3 100644 (file)
@@ -95,6 +95,7 @@ class ComponentReflectionTest(fixtures.TablesTest):
     @classmethod
     def define_index(cls, metadata, users):
         Index("users_t_idx", users.c.test1, users.c.test2)
+        Index("users_all_idx", users.c.user_id, users.c.test2, users.c.test1)
 
     @classmethod
     def define_views(cls, metadata, schema):
@@ -339,7 +340,11 @@ class ComponentReflectionTest(fixtures.TablesTest):
         expected_indexes = [
             {'unique': False,
              'column_names': ['test1', 'test2'],
-             'name': 'users_t_idx'}]
+             'name': 'users_t_idx'},
+            {'unique': False,
+             'column_names': ['user_id', 'test2', 'test1'],
+             'name': 'users_all_idx'}
+        ]
         index_names = [d['name'] for d in indexes]
         for e_index in expected_indexes:
             assert e_index['name'] in index_names