From: Mike Bayer Date: Fri, 20 May 2011 21:56:29 +0000 (-0400) Subject: - Fixed bug affecting PG 9 whereby index reflection X-Git-Tag: rel_0_6_8~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f50e686f77e520e1c8a93de47f9ad633d2777400;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed bug affecting PG 9 whereby index reflection would fail if against a column whose name had changed. [ticket:2141]. --- diff --git a/CHANGES b/CHANGES index bbf39408aa..7f9063a990 100644 --- 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 diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index d5e3be1e4b..465bfe0ea4 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -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 diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index 118a9eb271..18c4477ac7 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -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'