4

I edited two fields on a model and changed them from IntegerFields to TimeFields:

class Model(models.Model):
    start_time = models.TimeField()
    end_time = models.TimeField()

I'm using these two fields to save a naive time, which is not related to any geographical notion of time, and thus has no real 'time zone' (think something similar to race times). My local database is PostgreSQL.

However, the south migration generated from this change fails with the following error:

> main:0005_auto__chg_field_model_start_time__chg_field_model_end_time
FATAL ERROR - The following SQL query failed: ALTER TABLE "main_model" ALTER COLUMN "start_time" TYPE time, ALTER COLUMN "start_time" SET NOT NULL, ALTER COLUMN "start_time" DROP DEFAULT;

...

File ".../lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute
    return self.cursor.execute(query, args)
django.db.utils.DatabaseError: column "start_time" cannot be cast to type time without time zone

The failed migration has this:

class Migration(SchemaMigration):

    def forwards(self, orm):

        # Changing field 'Model.start_time'
        db.alter_column('main_model', 'start_time', self.gf('django.db.models.fields.TimeField')())

        # Changing field 'Model.end_time'
        db.alter_column('main_model', 'end_time', self.gf('django.db.models.fields.TimeField')())

Any idea on how to make postgres happy about this migration?

P.S. I'm in the midst of development, so I really don't care about any data migrations. You may assume the DB is empty.

diegueus9
  • 29,351
  • 16
  • 62
  • 74
Yuval Adam
  • 161,610
  • 92
  • 305
  • 395

3 Answers3

5

Since you don't care about data, the simplest way would be to delete the column then add it again with type Time.

Either edit the current migration manually to do this. Or delete this migration, then comment the field and run schemamigration --auto then add the field and run it again.

Maccesch
  • 1,998
  • 1
  • 18
  • 27
0

I ended up manually editing the migration script (Thanks @Maccesch) such that all alter_column() calls are replaced with delete_column() followed by an add_column().

Note that this means that no data migration is done and any data existing before this migration will be deleted.

Code:

def forwards(self, orm):

    # NOTE: NO MIGRATION HERE!!
    # THIS _WILL_ CAUSE DATA LOSS

    # Changing field 'Model.start_time'
    db.delete_column('main_model', 'start_time')
    db.add_column('main_model', 'start_time', self.gf('django.db.models.fields.TimeField')())

    # Changing field 'Model.end_time'
    db.delete_column('main_model', 'end_time')
    db.add_column('main_model', 'end_time', self.gf('django.db.models.fields.TimeField')())

backwards() is similarly implemented.

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
-1

I too have come across this problem, the problem was with south's migrations when creating the new test database. Placing

SOUTH_TESTS_MIGRATE = False

into your settings file fixed the issue for me.

Salyangoz
  • 287
  • 2
  • 14