Changeset 5792
- Timestamp:
- 08/03/07 15:49:19 (1 year ago)
- Files:
-
- django/branches/schema-evolution/django/db/backends/postgresql_psycopg2/base.py (modified) (1 diff)
- django/branches/schema-evolution/django/db/backends/postgresql_psycopg2/introspection.py (modified) (1 diff)
- django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/schema-evolution/django/db/backends/postgresql_psycopg2/base.py
r5785 r5792 226 226 return output 227 227 228 def get_change_table_name_sql( table_name, old_table_name ): 229 output = [] 230 output.append('ALTER TABLE '+ quote_name(old_table_name) +' RENAME TO '+ quote_name(table_name) + ';') 231 return output 232 233 def get_change_column_name_sql( table_name, indexes, old_col_name, new_col_name, col_def ): 234 # TODO: only supports a single primary key so far 235 pk_name = None 236 for key in indexes.keys(): 237 if indexes[key]['primary_key']: pk_name = key 238 output = [] 239 output.append( 'ALTER TABLE '+ quote_name(table_name) +' RENAME COLUMN '+ quote_name(old_col_name) +' TO '+ quote_name(new_col_name) +';' ) 240 return output 241 242 def get_change_column_def_sql( table_name, col_name, col_type, null, unique, primary_key ): 243 output = [] 244 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ADD COLUMN '+ quote_name(col_name+'_tmp') +' '+ col_type + ';' ) 245 output.append( 'UPDATE '+ quote_name(table_name) +' SET '+ quote_name(col_name+'_tmp') +' = '+ quote_name(col_name) + ';' ) 246 output.append( 'ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) +';' ) 247 output.append( 'ALTER TABLE '+ quote_name(table_name) +' RENAME COLUMN '+ quote_name(col_name+'_tmp') +' TO '+ quote_name(col_name) + ';' ) 248 if not null: 249 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ALTER COLUMN '+ quote_name(col_name) +' SET NOT NULL;' ) 250 if unique: 251 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ADD CONSTRAINT '+ table_name +'_'+ col_name +'_unique_constraint UNIQUE('+ col_name +');' ) 252 253 return output 254 255 def get_add_column_sql( table_name, col_name, col_type, null, unique, primary_key ): 256 output = [] 257 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ADD COLUMN '+ quote_name(col_name) +' '+ col_type + ';' ) 258 if not null: 259 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ALTER COLUMN '+ quote_name(col_name) +' SET NOT NULL;' ) 260 if unique: 261 output.append( 'ALTER TABLE '+ quote_name(table_name) +' ADD CONSTRAINT '+ table_name +'_'+ col_name +'_unique_constraint UNIQUE('+ col_name +');' ) 262 return output 263 264 def get_drop_column_sql( table_name, col_name ): 265 output = [] 266 output.append( 'ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) + ';' ) 267 return output 268 228 269 OPERATOR_MAPPING = { 229 270 'exact': '= %s', django/branches/schema-evolution/django/db/backends/postgresql_psycopg2/introspection.py
r5734 r5792 64 64 return indexes 65 65 66 def get_columns(cursor, table_name): 67 try: 68 cursor.execute("SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), (SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), a.attnotnull, a.attnum, pg_catalog.col_description(a.attrelid, a.attnum) FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid from pg_catalog.pg_class c where c.relname ~ '^%s$') AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum" % table_name) 69 return [row[0] for row in cursor.fetchall()] 70 except: 71 return [] 72 73 def get_known_column_flags( cursor, table_name, column_name ): 74 # print "SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), (SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), a.attnotnull, a.attnum, pg_catalog.col_description(a.attrelid, a.attnum) FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid from pg_catalog.pg_class c where c.relname ~ '^%s$') AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum" % table_name 75 cursor.execute("SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), (SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), a.attnotnull, a.attnum, pg_catalog.col_description(a.attrelid, a.attnum) FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid from pg_catalog.pg_class c where c.relname ~ '^%s$') AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum" % table_name) 76 dict = {} 77 dict['primary_key'] = False 78 dict['foreign_key'] = False 79 dict['unique'] = False 80 dict['default'] = '' 81 dict['allow_null'] = False 82 83 for row in cursor.fetchall(): 84 if row[0] == column_name: 85 86 # maxlength check goes here 87 if row[1][0:17]=='character varying': 88 dict['maxlength'] = row[1][18:len(row[1])-1] 89 90 # null flag check goes here 91 dict['allow_null'] = not row[3] 92 93 # pk, fk and unique checks go here 94 # print "select pg_constraint.conname, pg_constraint.contype, pg_attribute.attname from pg_constraint, pg_attribute where pg_constraint.conrelid=pg_attribute.attrelid and pg_attribute.attnum=any(pg_constraint.conkey) and pg_constraint.conname~'^%s'" % table_name 95 unique_conname = None 96 shared_unique_connames = set() 97 cursor.execute("select pg_constraint.conname, pg_constraint.contype, pg_attribute.attname from pg_constraint, pg_attribute, pg_class where pg_constraint.conrelid=pg_class.oid and pg_constraint.conrelid=pg_attribute.attrelid and pg_attribute.attnum=any(pg_constraint.conkey) and pg_class.relname='%s'" % table_name ) 98 for row in cursor.fetchall(): 99 # print row 100 if row[2] == column_name: 101 if row[1]=='p': dict['primary_key'] = True 102 if row[1]=='f': dict['foreign_key'] = True 103 if row[1]=='u': unique_conname = row[0] 104 else: 105 if row[1]=='u': shared_unique_connames.add( row[0] ) 106 if unique_conname and unique_conname not in shared_unique_connames: 107 dict['unique'] = True 108 109 # default value check goes here 110 cursor.execute("select pg_attribute.attname, adsrc from pg_attrdef, pg_attribute WHERE pg_attrdef.adrelid=pg_attribute.attrelid and pg_attribute.attnum=pg_attrdef.adnum and pg_attrdef.adrelid = (SELECT c.oid from pg_catalog.pg_class c where c.relname ~ '^%s$')" % table_name ) 111 for row in cursor.fetchall(): 112 if row[0] == column_name: 113 if row[1][0:7] == 'nextval': continue 114 dict['default'] = row[1][1:row[1].index("'",1)] 115 116 # print table_name, column_name, dict 117 return dict 118 66 119 # Maps type codes to Django Field types. 67 120 DATA_TYPES_REVERSE = { django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py
r5787 r5792 21 21 class Meta: 22 22 aka = ('PersonOld', 'OtherBadName') 23 24 class Muebles(models.Model): 25 tipo = models.CharField(maxlength=40) 26 # new fields 27 fecha_publicacion = models.DateTimeField('date published') 23 28 24 29 __test__ = {'API_TESTS':""" … … 35 40 # the table as it is supposed to be 36 41 >>> create_table_sql = management.get_sql_all(app) 37 >>> print create_table_sql38 ['CREATE TABLE `schema_evolution_person` (\\n `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\\n `name` varchar(20) NOT NULL,\\n `gender` varchar(1) NOT NULL,\\n `gender2` varchar(1) NOT NULL\\n)\\n;']39 42 40 43 # make sure we don't evolve an unedited table … … 90 93 >>> management.get_sql_evolution(app) 91 94 ['ALTER TABLE `schema_evolution_person` MODIFY COLUMN `name` varchar(20) NOT NULL;'] 92 """ 93 94 if settings.DATABASE_ENGINE == 'postgresql': 95 96 # reset the db 97 >>> cursor.execute('DROP TABLE schema_evolution_person;'); cursor.execute(create_table_sql[0]) 98 0L\n0L 99 100 # delete a datetime column pair, so it looks like we've recently added a datetime field 101 >>> for sql in backend.get_drop_column_sql( 'schema_evolution_muebles', 'fecha_publicacion' ): print sql; cursor.execute(sql) 102 ALTER TABLE `schema_evolution_muebles` DROP COLUMN `fecha_publicacion`; 103 0L 104 >>> management.get_sql_evolution(app) 105 ['ALTER TABLE `schema_evolution_muebles` ADD COLUMN `fecha_publicacion` datetime NOT NULL;'] 106 107 """ 108 109 if settings.DATABASE_ENGINE == 'postgresql' or settings.DATABASE_ENGINE == 'postgresql_psycopg2' : 95 110 __test__['API_TESTS'] += """ 96 111 # the table as it is supposed to be 97 112 >>> create_table_sql = management.get_sql_all(app) 98 >>> print create_table_sql99 ['CREATE TABLE "schema_evolution_person" (\\n "id" serial NOT NULL PRIMARY KEY,\\n "name" varchar(20) NOT NULL,\\n "gender" varchar(1) NOT NULL,\\n "gender2" varchar(1) NOT NULL\\n)\\n;']100 113 101 114 # make sure we don't evolve an unedited table … … 140 153 ['ALTER TABLE "schema_evolution_person" ADD COLUMN "name_tmp" varchar(20);', 'UPDATE "schema_evolution_person" SET "name_tmp" = "name";', 'ALTER TABLE "schema_evolution_person" DROP COLUMN "name";', 'ALTER TABLE "schema_evolution_person" RENAME COLUMN "name_tmp" TO "name";', 'ALTER TABLE "schema_evolution_person" ALTER COLUMN "name" SET NOT NULL;'] 141 154 155 # reset the db 156 >>> cursor.execute('DROP TABLE schema_evolution_person;'); cursor.execute(create_table_sql[0]) 157 158 # delete a datetime column pair, so it looks like we've recently added a datetime field 159 >>> for sql in backend.get_drop_column_sql( 'schema_evolution_muebles', 'fecha_publicacion' ): print sql; cursor.execute(sql) 160 ALTER TABLE "schema_evolution_muebles" DROP COLUMN "fecha_publicacion"; 161 >>> management.get_sql_evolution(app) 162 ['ALTER TABLE "schema_evolution_muebles" ADD COLUMN "fecha_publicacion" timestamp with time zone;', 'ALTER TABLE "schema_evolution_muebles" ALTER COLUMN "fecha_publicacion" SET NOT NULL;'] 142 163 """ 143 164 … … 146 167 # the table as it is supposed to be 147 168 >>> create_table_sql = management.get_sql_all(app) 148 >>> print create_table_sql149 ['CREATE TABLE "schema_evolution_person" (\\n "id" integer NOT NULL UNIQUE PRIMARY KEY,\\n "name" varchar(20) NOT NULL,\\n "gender" varchar(1) NOT NULL,\\n "gender2" varchar(1) NOT NULL\\n)\\n;']150 169 151 170 # make sure we don't evolve an unedited table … … 244 263 >>> management.get_sql_evolution(app) 245 264 ['-- FYI: sqlite does not support changing columns, so we create a new "schema_evolution_person" and delete the old (ie, this could take a while)', 'ALTER TABLE "schema_evolution_person" RENAME TO "schema_evolution_person_1337_TMP";', 'CREATE TABLE "schema_evolution_person" (\\n "id" integer NOT NULL UNIQUE PRIMARY KEY,\\n "name" varchar(20) NOT NULL,\\n "gender" varchar(1) NOT NULL,\\n "gender2" varchar(1) NOT NULL\\n)\\n;', 'INSERT INTO "schema_evolution_person" SELECT "id","name","gender","gender2" FROM "schema_evolution_person_1337_TMP";', 'DROP TABLE "schema_evolution_person_1337_TMP";'] 246 """ 247 265 266 # reset the db 267 >>> cursor.execute('DROP TABLE schema_evolution_person;').__class__ 268 <class 'django.db.backends.sqlite3.base.SQLiteCursorWrapper'> 269 >>> cursor.execute(create_table_sql[0]).__class__ 270 <class 'django.db.backends.sqlite3.base.SQLiteCursorWrapper'> 271 272 # delete a datetime column pair, so it looks like we've recently added a datetime field 273 >>> for sql in ['DROP TABLE schema_evolution_muebles;','CREATE TABLE "schema_evolution_muebles" ("id" integer NOT NULL UNIQUE PRIMARY KEY,"tipo" varchar(40) NOT NULL);']: cursor.execute(sql).__class__ 274 <class 'django.db.backends.sqlite3.base.SQLiteCursorWrapper'> 275 <class 'django.db.backends.sqlite3.base.SQLiteCursorWrapper'> 276 >>> management.get_sql_evolution(app) 277 ['ALTER TABLE "schema_evolution_muebles" ADD COLUMN "fecha_publicacion" datetime NOT NULL;'] 278 279 280 """ 281
