Author: danderson
Date: 2007-08-01 12:51:59 -0500 (Wed, 01 Aug 2007)
New Revision: 5784

Modified:
   django/branches/schema-evolution/django/core/management.py
   django/branches/schema-evolution/django/db/backends/mysql/base.py
   django/branches/schema-evolution/django/db/backends/postgresql/base.py
   
django/branches/schema-evolution/django/db/backends/postgresql/introspection.py
   django/branches/schema-evolution/django/db/backends/sqlite3/base.py
   django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py
Log:
schema-evolution:
fixed postgresql constraint lookup after a table rename bug
pulled table renames into the backends
added postgresql unit tests



Modified: django/branches/schema-evolution/django/core/management.py
===================================================================
--- django/branches/schema-evolution/django/core/management.py  2007-08-01 
05:52:18 UTC (rev 5783)
+++ django/branches/schema-evolution/django/core/management.py  2007-08-01 
17:51:59 UTC (rev 5784)
@@ -5,6 +5,7 @@
 from django.core.exceptions import ImproperlyConfigured
 from optparse import OptionParser
 from django.utils import termcolors
+from django.conf import settings
 import os, re, shutil, sys, textwrap
 
 try:
@@ -591,9 +592,9 @@
     if klass._meta.db_table in table_list:
         return [], None
     if klass._meta.aka in table_list:
-        return [ 'ALTER TABLE '+ backend.quote_name(klass._meta.aka) +' RENAME 
TO '+ backend.quote_name(klass._meta.db_table) + ';' ], klass._meta.aka
+        return [ backend.get_change_table_name_sql( klass._meta.db_table, 
klass._meta.aka) ], klass._meta.aka
     elif len(set(klass._meta.aka) & set(table_list))==1:
-        return [ 'ALTER TABLE '+ backend.quote_name(klass._meta.aka[0]) +' 
RENAME TO '+ backend.quote_name(klass._meta.db_table) + ';' ], 
klass._meta.aka[0]
+        return [ backend.get_change_table_name_sql( klass._meta.db_table, 
klass._meta.aka[0]) ], klass._meta.aka[0]
     else:
         return [], None
     
@@ -643,6 +644,7 @@
         db_table = new_table_name
     for f in opts.fields:
         existing_fields = introspection.get_columns(cursor,db_table)
+#        print existing_fields
         cf = None # current field, ie what it is before any renames
         if f.column in existing_fields:
             cf = f.column
@@ -655,10 +657,11 @@
         data_type = f.get_internal_type()
         if data_types.has_key(data_type):
             column_flags = introspection.get_known_column_flags(cursor, 
db_table, cf)
+#            print db_table, cf, column_flags
             if column_flags['allow_null']!=f.null or \
                     ( not f.primary_key and isinstance(f, CharField) and 
column_flags['maxlength']!=str(f.maxlength) ) or \
                     ( not f.primary_key and isinstance(f, SlugField) and 
column_flags['maxlength']!=str(f.maxlength) ) or \
-                    column_flags['unique']!=f.unique or \
+                    ( column_flags['unique']!=f.unique and ( 
settings.DATABASE_ENGINE!='postgresql' or not f.primary_key ) ) or \
                     column_flags['primary_key']!=f.primary_key:
                     #column_flags['foreign_key']!=f.foreign_key:
 #                print 

Modified: django/branches/schema-evolution/django/db/backends/mysql/base.py
===================================================================
--- django/branches/schema-evolution/django/db/backends/mysql/base.py   
2007-08-01 05:52:18 UTC (rev 5783)
+++ django/branches/schema-evolution/django/db/backends/mysql/base.py   
2007-08-01 17:51:59 UTC (rev 5784)
@@ -242,6 +242,9 @@
     # No sequence reset required
     return []
 
+def get_change_table_name_sql( table_name, old_table_name ):
+    return 'ALTER TABLE '+ quote_name(old_table_name) +' RENAME TO '+ 
quote_name(table_name) + ';'
+
 def get_change_column_name_sql( table_name, indexes, old_col_name, 
new_col_name, col_def ):
     # mysql doesn't support column renames (AFAIK), so we fake it
     # TODO: only supports a single primary key so far

Modified: django/branches/schema-evolution/django/db/backends/postgresql/base.py
===================================================================
--- django/branches/schema-evolution/django/db/backends/postgresql/base.py      
2007-08-01 05:52:18 UTC (rev 5783)
+++ django/branches/schema-evolution/django/db/backends/postgresql/base.py      
2007-08-01 17:51:59 UTC (rev 5784)
@@ -282,6 +282,11 @@
         return s
     return smart_unicode(s)
 
+def get_change_table_name_sql( table_name, old_table_name ):
+    output = []
+    output.append('ALTER TABLE '+ quote_name(old_table_name) +' RENAME TO '+ 
quote_name(table_name) + ';')
+    return '\n'.join(output)
+
 def get_change_column_name_sql( table_name, indexes, old_col_name, 
new_col_name, col_def ):
     # TODO: only supports a single primary key so far
     pk_name = None

Modified: 
django/branches/schema-evolution/django/db/backends/postgresql/introspection.py
===================================================================
--- 
django/branches/schema-evolution/django/db/backends/postgresql/introspection.py 
    2007-08-01 05:52:18 UTC (rev 5783)
+++ 
django/branches/schema-evolution/django/db/backends/postgresql/introspection.py 
    2007-08-01 17:51:59 UTC (rev 5784)
@@ -97,8 +97,9 @@
 #    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 
     unique_conname = None
     shared_unique_connames = set()
-    cursor.execute("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 )
+    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 )
     for row in cursor.fetchall():
+#        print row
         if row[2] == column_name:
             if row[1]=='p': dict['primary_key'] = True
             if row[1]=='f': dict['foreign_key'] = True

Modified: django/branches/schema-evolution/django/db/backends/sqlite3/base.py
===================================================================
--- django/branches/schema-evolution/django/db/backends/sqlite3/base.py 
2007-08-01 05:52:18 UTC (rev 5783)
+++ django/branches/schema-evolution/django/db/backends/sqlite3/base.py 
2007-08-01 17:51:59 UTC (rev 5784)
@@ -214,6 +214,9 @@
     except:
         return False
 
+def get_change_table_name_sql( table_name, old_table_name ):
+    return 'ALTER TABLE '+ quote_name(old_table_name) +' RENAME TO '+ 
quote_name(table_name) + ';'
+
 def get_change_column_name_sql( table_name, indexes, old_col_name, 
new_col_name, col_def ):
     # sqlite doesn't support column renames, so we fake it
     # TODO: only supports a single primary key so far

Modified: 
django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py
===================================================================
--- 
django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py    
    2007-08-01 05:52:18 UTC (rev 5783)
+++ 
django/branches/schema-evolution/tests/modeltests/schema_evolution/models.py    
    2007-08-01 17:51:59 UTC (rev 5784)
@@ -3,6 +3,7 @@
 """
 
 from django.db import models
+from django.conf import settings
 
 GENDER_CHOICES = (
     ('M', 'Male'),
@@ -27,7 +28,10 @@
 >>> from django.db import connection, get_introspection_module
 >>> app = models.get_apps()[-1]
 >>> cursor = connection.cursor()
+"""}
 
+if settings.DATABASE_ENGINE == 'mysql':
+    __test__['API_TESTS'] += """
 # the table as it is supposed to be
 >>> create_table_sql = management.get_sql_all(app)
 >>> print create_table_sql
@@ -85,7 +89,55 @@
 0L
 >>> management.get_sql_evolution(app)
 ['ALTER TABLE `schema_evolution_person` MODIFY COLUMN `name` varchar(20) NOT 
NULL;']
+"""
 
+if settings.DATABASE_ENGINE == 'postgresql':
+    __test__['API_TESTS'] += """
+# the table as it is supposed to be
+>>> create_table_sql = management.get_sql_all(app)
+>>> print create_table_sql
+['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;']
 
-"""}
+# make sure we don't evolve an unedited table
+>>> management.get_sql_evolution(app)
+[]
 
+# delete a column, so it looks like we've recently added a field
+>>> cursor.execute( backend.get_drop_column_sql( 'schema_evolution_person', 
'gender' ) )
+>>> management.get_sql_evolution(app)
+['ALTER TABLE "schema_evolution_person" ADD COLUMN "gender" 
varchar(1);\\nALTER TABLE "schema_evolution_person" ALTER COLUMN "gender" SET 
NOT NULL;']
+
+# reset the db
+>>> cursor.execute('DROP TABLE schema_evolution_person;'); 
cursor.execute(create_table_sql[0])
+
+# add a column, so it looks like we've recently deleted a field
+>>> cursor.execute( backend.get_add_column_sql( 'schema_evolution_person', 
'gender_nothere', 'varchar(1)', True, False, False ) )
+>>> management.get_sql_evolution(app)
+['-- warning: as the following may cause data loss, it/they must be run 
manually', u'-- ALTER TABLE "schema_evolution_person" DROP COLUMN 
"gender_nothere";', '-- end warning']
+
+# reset the db
+>>> cursor.execute('DROP TABLE schema_evolution_person;'); 
cursor.execute(create_table_sql[0])
+
+# rename column, so it looks like we've recently renamed a field
+>>> cursor.execute( backend.get_change_column_name_sql( 
'schema_evolution_person', {}, 'gender2', 'gender_old', 'varchar(1)' ) )
+>>> management.get_sql_evolution(app)
+['ALTER TABLE "schema_evolution_person" RENAME COLUMN "gender_old" TO 
"gender2";']
+
+# reset the db
+>>> cursor.execute('DROP TABLE schema_evolution_person;'); 
cursor.execute(create_table_sql[0])
+
+# rename table, so it looks like we've recently renamed a model
+>>> cursor.execute( backend.get_change_table_name_sql( 
'schema_evolution_personold', 'schema_evolution_person' ) )
+>>> management.get_sql_evolution(app)
+['ALTER TABLE "schema_evolution_personold" RENAME TO 
"schema_evolution_person";']
+
+# reset the db
+>>> cursor.execute(create_table_sql[0])
+
+# change column flags, so it looks like we've recently changed a column flag
+>>> cursor.execute( backend.get_change_column_def_sql( 
'schema_evolution_person', 'name', 'varchar(10)', True, False, False ) )
+>>> management.get_sql_evolution(app)
+['ALTER TABLE "schema_evolution_person" ADD COLUMN "name_tmp" 
varchar(20);\\nUPDATE "schema_evolution_person" SET "name_tmp" = 
"name";\\nALTER TABLE "schema_evolution_person" DROP COLUMN "name";\\nALTER 
TABLE "schema_evolution_person" RENAME COLUMN "name_tmp" TO "name";\\nALTER 
TABLE "schema_evolution_person" ALTER COLUMN "name" SET NOT NULL;']
+
+"""
+


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to