Django Migration RunSQL conditionally for database type

I am trying to use Django migrations.RunSQL to run arbitrary SQL code. I would like to start this migration only for certain db servers (for example, only for postgres).

I would consider using something like this , but I do not see the DB connection information in the Migration class.

+8
django django-orm django-migrations django-database
source share
4 answers

I had the same need. I had to edit the migration, which sets the initial value of the sequence, which works on postgres, but not sqlite. This is how I wrapped RunSQL inside RunPython, following the documentation related to Daniel.

 from django.db import migrations def forwards(apps, schema_editor): if not schema_editor.connection.vendor == 'postgres': return migrations.RunSQL( "alter sequence api_consumer_id_seq restart with 1000500;") class Migration(migrations.Migration): dependencies = [ ('api', '0043_auto_20160416_2313'), ] operations = [ migrations.RunPython(forwards), ] 
+4
source share

This is how I solved the problem, since I could not get RunSQL to work inside RunPython . Fortunately, the schema_editor object has an execute() method.

 def forwards(apps, schema_editor): if not schema_editor.connection.vendor.startswith('postgres'): logger.info('Database vendor: {}'.format(schema_editor.connection.vendor)) logger.info('Skipping migration without attempting to ADD CONSTRAINT') return schema_editor.execute('ALTER TABLE my_table ADD CONSTRAINT my_constraint (my_field != \'NaN\';)') def backwards(apps, schema_editor): if not schema_editor.connection.vendor.startswith('postgres'): logger.info('Database vendor: {}'.format(schema_editor.connection.vendor)) logger.info('Skipping migration without attempting to DROP CONSTRAINT') return schema_editor.execute('ALTER TABLE my_table DROP CONSTRAINT my_constraint;') class Migration(migrations.Migration): dependencies = [ ... ] operations = [ migrations.RunPython(forwards, backwards, atomic=True) ] 
+4
source share

Today I solved a similar problem - I need to migrate to create a new model, but only for postgres DB, and I found this question. However, Matthew's answer did not help me. In fact, I'm not sure if it works at all. This is because the line with migrations.RunSQL(...) does not actually run SQL; it creates a new object of type RunSQL , which is Command , and then immediately discards it.

This is how I decided to solve the problem if someone tries to find "conditional django migration" in the future:

 from __future__ import unicode_literals import django.contrib.postgres.fields from django.db import migrations, models class PostgresOnlyCreateModel(migrations.CreateModel): def database_forwards(self, app_label, schema_editor, from_state, to_state): if schema_editor.connection.vendor.startswith("postgres"): super(PostgresOnlyCreateModel, self).database_forwards(app_label, schema_editor, from_state, to_state) def database_backwards(self, app_label, schema_editor, from_state, to_state): if schema_editor.connection.vendor.startswith("postgres"): super(PostgresOnlyCreateModel, self).database_backwards(app_label, schema_editor, from_state, to_state) class Migration(migrations.Migration): dependencies = [ ...whatever... ] operations = [ PostgresOnlyCreateModel( name='...whatever...', fields=[...whatever...], ), ] 
+3
source share

This information is not provided in the Migration class, it is provided in the schema_editor attribute passed to RunPython. See the documentation for some examples of using this.

0
source share

All Articles