Commit 9a2924d5 authored by Vladimir Mencl's avatar Vladimir Mencl

South migrations: add PostgreSQL issue workaround

Add workaround for an issue with running South Migrations on PostgreSQL.

Migration 0022_auto__chg_field_institutiondetails_number_id__del_field_instrealmmon_i.py breaks on PostgreSQL with:

ERROR:  column "realm_id" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.
STATEMENT:  ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer,
            ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT;
This is a known problem: http://south.aeracode.org/ticket/484
(PostgreSQL will not automatically convert and conversion must be provided with the USING clause)
Workaround: For PostgreSQL invoke a direct SQL statement amended with a USING clause to do the converion explicitly.

Rely on db._get_connection().vendor to determine if we are running on PostgreSQL.

Credits:
* Workaround via db.execute:
  http://codeinthehole.com/writing/altering-postgres-table-columns-with-south/
* USING syntax to convert integers:
  http://stackoverflow.com/questions/13170570/change-type-of-varchar-field-to-integer-cannot-be-cast-automatically-to-type-i
parent 94864f05
......@@ -17,7 +17,22 @@ class Migration(SchemaMigration):
# Renaming column for 'InstRealmMon.realm' to match new field type.
db.rename_column('edumanage_instrealmmon', 'realm', 'realm_id')
# Changing field 'InstRealmMon.realm'
db.alter_column('edumanage_instrealmmon', 'realm_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['edumanage.InstRealm']))
# WORKAROUND NEEDED
# This migration breaks with PostgreSQL with:
# ERROR: column "realm_id" cannot be cast automatically to type integer
# HINT: Specify a USING expression to perform the conversion.
# STATEMENT: ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer,
# ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT;
# This is a known problem: http://south.aeracode.org/ticket/484
# (PostgreSQL will not automatically convert and conversion must be provided with the USING clause)
# Workaround: For PostgreSQL invoke a direct SQL statement amended with a USING clause to do the converion explicitly.
# Credits:
# * http://codeinthehole.com/writing/altering-postgres-table-columns-with-south/
# * http://stackoverflow.com/questions/13170570/change-type-of-varchar-field-to-integer-cannot-be-cast-automatically-to-type-i
if ( db._get_connection().vendor == "postgresql" ):
db.execute('ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer USING (trim(realm_id)::integer), ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT;')
else:
db.alter_column('edumanage_instrealmmon', 'realm_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['edumanage.InstRealm']))
# Adding index on 'InstRealmMon', fields ['realm']
db.create_index('edumanage_instrealmmon', ['realm_id'])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment