Anonymous avatar Anonymous committed 88eb586

Fix from #125 for me breaking datetime with time zone.

Comments (0)

Files changed (3)

south/db/generic.py

                 self.alter_column(table_name, name, field, explicit_name=False)
     
 
+    def _db_type_for_alter_column(self, field):
+        """
+        Returns a field's type suitable for ALTER COLUMN.
+        By default it just returns field.db_type().
+        To be overriden by backend specific subclasses
+        @param field: The field to generate type for
+        """
+        return field.db_type()
+    
     def alter_column(self, table_name, name, field, explicit_name=True):
         """
         Alters the given column name so it will match the given field.
         # First, change the type
         params = {
             "column": qn(name),
-            "type": field.db_type().split(" ")[0], # The type might have CHECK... in it.
+            "type": self._db_type_for_alter_column(field)            
         }
 
         # SQLs is a list of (SQL, values) pairs.

south/db/postgresql_psycopg2.py

 
-from django.db import connection
+from django.db import connection, models
 from south.db import generic
 
 class DatabaseOperations(generic.DatabaseOperations):
     def rename_index(self, old_index_name, index_name):
         "Rename an index individually"
         generic.DatabaseOperations.rename_table(self, old_index_name, index_name)
+
+    def _db_type_for_alter_column(self, field):
+        """
+        Returns a field's type suitable for ALTER COLUMN.
+        Strips CHECKs from PositiveSmallIntegerField) and PositiveIntegerField
+        @param field: The field to generate type for
+        """
+        if isinstance(field, models.PositiveSmallIntegerField) or isinstance(field, models.PositiveIntegerField):
+            return field.db_type().split(" ")[0]
+        return super(DatabaseOperations, self)._db_type_for_alter_column(field)

south/tests/db.py

         
         db.rollback_transaction()
         db.delete_table("test4")
+        
+    def test_alter_column_postgres_multiword(self):
+        """
+        Tests altering columns with multiple words in Postgres types (issue #125)
+        e.g. 'datetime with time zone', look at django/db/backends/postgresql/creation.py
+        """
+        db.create_table("postgres_multiword", [
+            (('datetime'), models.DateTimeField(null=True)),
+            (('integer'), models.PositiveIntegerField(null=True)),
+            (('smallint'), models.PositiveSmallIntegerField(null=True)),
+            (('float'), models.FloatField(null=True)),
+        ])
+        
+        # test if 'double precision' is preserved
+        db.alter_column('postgres_multiword', 'float', models.FloatField('float', null=True))
+
+        # test if 'CHECK ("%(column)s" >= 0)' is stripped
+        db.alter_column('postgres_multiword', 'integer', models.PositiveIntegerField(null=True))
+        db.alter_column('postgres_multiword', 'smallint', models.PositiveSmallIntegerField(null=True))
+
+        # test if 'with timezone' is preserved
+        db.start_transaction()
+        db.execute("INSERT INTO postgres_multiword (datetime) VALUES ('2009-04-24 14:20:55+02')")
+        db.alter_column('postgres_multiword', 'datetime', models.DateTimeField(auto_now=True))
+        assert db.execute("SELECT datetime = '2009-04-24 14:20:55+02' FROM postgres_multiword")[0][0]
+        db.rollback_transaction()
+
+        
+        db.delete_table("postgres_multiword")
     
     def test_alter_constraints(self):
         """
         else:
             self.fail("Could insert non-unique pair.")
         db.delete_unique("test_unique", ["spam", "eggs", "ham_id"])
-        
+        
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.