Ticket #17785: pscopg2-introspection.patch
File pscopg2-introspection.patch, 4.4 KB (added by , 13 years ago) |
---|
-
django/db/backends/postgresql_psycopg2/introspection.py
50 50 """ 51 51 Returns a dictionary of {field_index: (field_index_other_table, other_table)} 52 52 representing all relationships to the given table. Indexes are 0-based. 53 If a column gets deleted, attnum of the other columns does not change. You can't use attnum as 54 offset in the table description. 53 55 """ 56 cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)) 57 this_table_col_names=[col_desc[0] for col_desc in cursor.description] 54 58 cursor.execute(""" 55 SELECT con.conkey, con.confkey, c2.relname 59 SELECT 60 (SELECT attname FROM pg_attribute WHERE attnum=con.conkey[1] AND attrelid=con.conrelid), 61 (SELECT attname FROM pg_attribute WHERE attnum=con.confkey[1] AND attrelid=con.confrelid), 62 c2.relname 56 63 FROM pg_constraint con, pg_class c1, pg_class c2 57 64 WHERE c1.oid = con.conrelid 58 65 AND c2.oid = con.confrelid 59 66 AND c1.relname = %s 60 67 AND con.contype = 'f'""", [table_name]) 61 68 relations = {} 62 for row in cursor.fetchall(): 63 # row[0] and row[1] are single-item lists, so grab the single item. 64 relations[row[0][0] - 1] = (row[1][0] - 1, row[2]) 69 for this_col_name, other_col_name, other_table in list(cursor.fetchall()): 70 cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(other_table)) 71 other_table_col_names=[col_desc[0] for col_desc in cursor.description] 72 relations[this_table_col_names.index(this_col_name)] = (other_table_col_names.index(other_col_name), other_table) 65 73 return relations 66 74 67 75 def get_indexes(self, cursor, table_name): -
tests/regressiontests/introspection/tests.py
4 4 5 5 from django.db import connection 6 6 from django.test import TestCase, skipUnlessDBFeature, skipIfDBFeature 7 from django.db.utils import DatabaseError 7 8 8 9 from .models import Reporter, Article 9 10 … … 136 137 indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) 137 138 self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False}) 138 139 140 def test_introspection_after_drop_column(self): 141 cursor = connection.cursor() 142 cursor.execute('''CREATE TABLE "django_drop_col_other1" ("id" INTEGER CONSTRAINT "other1_pk_id" PRIMARY KEY)''') 143 cursor.execute('''CREATE TABLE "django_drop_col_other2" ("id" INTEGER CONSTRAINT "other2_pk_id" PRIMARY KEY)''') 144 cursor.execute('''CREATE TABLE "django_drop_col_test" ( 145 "id" INTEGER CONSTRAINT "pk_id" PRIMARY KEY, 146 "col_to_drop" INTEGER CONSTRAINT "fk_col_to_drop" REFERENCES "django_drop_col_other1" ("id"), 147 "col_fk" INTEGER CONSTRAINT "fk_col_fk" REFERENCES "django_drop_col_other2" ("id") 148 ) ''') 149 col_names = [col[0] for col in connection.introspection.get_table_description(cursor, "django_drop_col_test")] 150 self.assertEqual(col_names, ['id', 'col_to_drop', 'col_fk']) 151 rels=connection.introspection.get_relations(cursor, "django_drop_col_test") 152 self.assertEqual(rels, {1: (0, u'django_drop_col_other1'), 2: (0, u'django_drop_col_other2')}) 153 try: 154 cursor.execute('ALTER TABLE "django_drop_col_test" DROP COLUMN "col_to_drop"') 155 except DatabaseError: 156 return # sqlite does not support drop column 157 col_names = [col[0] for col in connection.introspection.get_table_description(cursor, "django_drop_col_test")] 158 self.assertEqual(col_names, ['id', 'col_fk']) 159 rels=connection.introspection.get_relations(cursor, "django_drop_col_test") 160 self.assertEqual(rels, {1: (0, u'django_drop_col_other2')}) 161 139 162 140 163 def datatype(dbtype, description): 141 164 """Helper to convert a data type into a string."""