Opened 8 years ago

Closed 8 years ago

#3790 closed (fixed)

New model object's pk clashes with fixture data

Reported by: scott@… Owned by: russellm
Component: Testing framework Version: master
Severity: Keywords: test fixture pk primary key
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I'm using fixtures with django.test.TestCase. If my test creates a model object and the fixture data already contains an object of the same type with pk=1, the new object will fail to save because of a pk clash. If my fixture data has pk=2, my created object is saved fine (with pk=1), but a subsequent object will fail with a pk clash (trying to use pk=2, already taken).

It's as if the sequence is not taking account of the primary key values that were explicitly set when the fixture was loaded. If I use psql to insert rows with pk specified, then insert rows without pk specified, the sequence handles it fine. I tested with Postgresql (8.1) using both the postgresql and postgresql_psycopg2 database engines.

Here's some example code to reproduce the problem (also app attached).

demo/models.py

from django.db import models

class Example(models.Model):
    name = models.CharField(maxlength=100)

demo/fixtures/example.json

[
    {
        "pk": 1,
        "model": "demo.example",
        "fields":
        {
            "name": "example 1"
        }
    }
]

demo/tests.py

from django.test import TestCase

from demo.models import Example

class ExampleTestCase(TestCase):
    fixtures = ['example']
    
    def test_example(self):
        new_example = Example.objects.create(name='new example')

./manage.py test demo

Error message:

======================================================================
ERROR: test_example (project.demo.tests.ExampleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/user/dev/project/web/project/../project/demo/tests.py", line 10, in test_example
    new_example = Example.objects.create(name='new example')
  File "/usr/lib/python2.4/site-packages/django/db/models/manager.py", line 79, in create
    return self.get_query_set().create(**kwargs)
  File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 262, in create
    obj.save()
  File "/usr/lib/python2.4/site-packages/django/db/models/base.py", line 238, in save
    ','.join(placeholders)), db_values)
IntegrityError: duplicate key violates unique constraint "demo_example_pkey"

Change History (3)

comment:1 Changed 8 years ago by jon.ballard

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 8 years ago by russellm

  • Owner changed from adrian to russellm
  • Triage Stage changed from Unreviewed to Accepted

Problem only exists with Postgres - SQLite and MySQL are unaffected. Problem is caused by the resetting of sequences during the flush.

comment:3 Changed 8 years ago by russellm

  • Resolution set to fixed
  • Status changed from new to closed

(In [4937]) Fixed #3790 -- Fixed a problem with sequence resetting during fixture loads when using Postgres. Thanks to Jon Ballard and scott@… for the report, and to Zach Thompson for suggesting a solution.

Note: See TracTickets for help on using tickets.
Back to Top