summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py30
-rw-r--r--test/dialect/test_postgresql.py22
3 files changed, 49 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index ee3183d18..7863daa8c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -135,6 +135,10 @@ CHANGES
- Fixed the psycopg2_version parsing in the
psycopg2 dialect.
+ - Fixed bug affecting PG 9 whereby index reflection
+ would fail if against a column whose name
+ had changed. [ticket:2141]. Also in 0.6.8.
+
- mssql
- Fixed bug in MSSQL dialect whereby the aliasing
applied to a schema-qualified table would leak
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index 7fdd74628..3193cde9e 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -1308,16 +1308,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
@@ -1343,7 +1358,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
diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py
index a15fc63df..391f12022 100644
--- a/test/dialect/test_postgresql.py
+++ b/test/dialect/test_postgresql.py
@@ -1541,6 +1541,28 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
'expression-based index idx3'
])
+ @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]
+
+ """
+
+ metadata = self.metadata
+
+ 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('+zxjdbc', 'psycopg2/pg8000 specific assertion')
@testing.fails_on('pypostgresql',