[Patch] Change 14413 breaks old fixtures with permissions
|Reported by:||Christian Hammond||Owned by:||nobody|
|Cc:||Triage Stage:||Ready for checkin|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Changeset 14413 introduced a regression with fixtures containing permissions. Any old fixtures that contain data for permissions on an object (such as a User) will fail on any unit test using them, or during a loaddata.
The cause appears to be that when creating the permissions in
contrib/auth/management/__init__.py:create_permissions, the ordering used before this change is no longer maintained, and as such the IDs of the permissions no longer match up. When a fixture attempts to install the permission, it will attempt to use a new ID that doesn't match what Django is now creating.
Updating the fixtures to use the new IDs results in regressions on older versions of Django for the same reason. This makes maintaining installable software that attempts to provide compatibility between Django versions a very difficult task.
I understand that the new logic is intended to speed up the test suite, but it's a fairly major regression.
To reproduce this, simply create a new site using an older Django revision (say, 14412), run syncdb, create the admin user, and then dumpdata to a fixture. Create a dummy unit test that loads the fixture. Run it and it will succeed. Upgrade to revision 14413 or newer and re-run the unit test. It will fail.
On sqlite, the error message is:
Problem installing fixture '/home/chipx86/temp/django-breakage-test/fixturetest/../fixturetest/myapp/fixtures/test_users.json': Traceback (most recent call last): File "/usr/local/lib/python2.6/dist-packages/django/core/management/commands/loaddata.py", line 174, in handle obj.save(using=using) File "/usr/local/lib/python2.6/dist-packages/django/core/serializers/base.py", line 165, in save models.Model.save_base(self.object, using=using, raw=True) File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 518, in save_base rows = manager.using(using).filter(pk=pk_val)._update(values) File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 490, in _update return query.get_compiler(self.db).execute_sql(None) File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 864, in execute_sql cursor = super(SQLUpdateCompiler, self).execute_sql(result_type) File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 730, in execute_sql cursor.execute(sql, params) File "/usr/local/lib/python2.6/dist-packages/django/db/backends/sqlite3/base.py", line 221, in execute return Database.Cursor.execute(self, query, params) IntegrityError: columns content_type_id, codename are not unique
The ordering appears to be incorrect due to the use of a
searched_perms. Switching to using a list for this solves the problem.
Providing a patch for this.