Search code examples
pythondjangosqlitedata-migration

Django transaction test case raises IntegrityError with data migration on sqlite


I'm trying to port an existing django 1.6 project with tests using LiveServerTestCase to django 1.7. I've converted the initial_data fixtures to data migrations. When I did that all my live server tests failed because the data was being flushed. I then stumbled upon the serialized_rollback option for TransactionTestCase and added that to my test classes. However now I'm getting the following error when I run my tests:

sqlite3.IntegrityError: UNIQUE constraint failed: django_content_type.app_label, django_content_type.model

I've replicated the problem in a sample app here: https://github.com/tctimmeh/djangomigrate

The model:

class SomeData(Model):
    value = IntegerField()

The data migration:

def createData(apps, schema_editor):
    SomeData = apps.get_model('mtestapp', 'SomeData')
    db_alias = schema_editor.connection.alias
    SomeData.objects.using(db_alias).bulk_create([
        SomeData(value = 1),
    ])

class Migration(migrations.Migration):
    dependencies = [
        ('mtestapp', '0001_initial'),
    ]
    operations = [
        RunPython(createData)
    ]

And the tests:

class TestIt(TransactionTestCase):
    serialized_rollback = True
    def test_one(self):
        self.assertEqual(1, SomeData.objects.all().count())
    def test_two(self):
        self.assertEqual(1, SomeData.objects.all().count())

One of those tests pass. The other raises the above-mentioned IntegrityError. Any idea why this might be?

Edit: I dug into it a bit more and it looks like the django.contrib.contenttypes app has a post_migrate management command that runs after the test database is flushed. Is there a way to prevent that command from running maybe?


Solution

  • This is fixed in Django 1.9: https://code.djangoproject.com/ticket/23727

    For earlier versions I worked around this problem by re-creating my static data as a setup step for every test.