Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django TransactionTestCase with rollback emulation

I'm using Django 1.7.7 with python 2.7.6 and Postgres as database and I had a problem with a TransactionTestCase. In my migrations I had two datamigrations and I wanted them to be available during the tests, so I added serialized_rollback = True to my test case (https://docs.djangoproject.com/en/1.7/topics/testing/overview/#test-case-serialized-rollback).

The first test of the test cases was ok, but then django was complaining with an IntegrityError:

IntegrityError: duplicate key value violates unique constraint "django_content_type_app_label_6032a1f08b99c274_uniq"
DETAIL:  Key (app_label, model)=(admin, logentry) already exists.

I managed to run the tests and to avoid this error by adding the following to my settings (https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-TEST_NON_SERIALIZED_APPS):

TEST_NON_SERIALIZED_APPS = ['django.contrib.contenttypes',
                            'django.contrib.auth']

But I would like to know why is this needed? Is this a bug in the rollback or is this a problem on my side?

like image 963
se7entyse7en Avatar asked Mar 24 '15 07:03

se7entyse7en


1 Answers

This issue is really well explained in django related ticket: https://code.djangoproject.com/ticket/23727

Quoted from there:

When using a TransactionTestCase with serialized_rollback=True, after creating the database and running its migrations (along with emitting the post_migrate signal), the contents of the database are serialized to _test_serialized_contents.

After the first test case, _fixture_teardown() would flush the tables but then the post_migrate signal would be emitted and new rows (with new PKs) would be created in the django_content_type table.

Then in any subsequent test cases in a suite, _fixture_setup() attempts to deserialize the content of _test_serialized_contents, but these rows are identical to the rows already in the database except for their PKs.

This causes an IntegrityError due to the unique constraint in the django_content_type table.

A patch has been created/released, but only for Django 1.9.x.

For previous versions, you should continue to use TEST_NON_SERIALIZED_APPS I guess...

like image 145
romgar Avatar answered Nov 08 '22 05:11

romgar