Opened 5 years ago

Closed 5 years ago

#13941 closed (fixed)

importing fixtures to postgres fails to set sequences correctly

Reported by: ales_zoulek Owned by: jbronn
Component: Database layer (models, ORM) Version: master
Severity: Keywords: postgres fixture
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


there seems to be a problem with django postgres backend, when
importing data from fixtures. Data are imported correctly, but the
sequences for primary keys are set incorrecly on models that have
generic.GenericRelation field. See example:

As a demo, those are just two models with generic relation.
from django.db import models
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType

class Tag(models.Model):
   name = models.CharField(max_length=30)
   content_type = models.ForeignKey(ContentType)
   object_id = models.PositiveIntegerField()
   content_object = generic.GenericForeignKey('content_type', 'object_id')

class Post(models.Model):
   name = models.CharField(max_length=30)
   text = models.TextField()
   tags = generic.GenericRelation('blog.Tag')

The loaddata management command calls at the end

connections[DEFAULT_DB_ALIAS].ops.sequence_reset_sql command

to update sq1 sequences. Let's see the result:

./manage shell
In [1]: from django.db import DEFAULT_DB_ALIAS, connections
In [2]: from import no_style
In [3]: from import Post
In [4]: connections[DEFAULT_DB_ALIAS].ops.sequence_reset_sql(no_style(), [Post])
['SELECT setval(pg_get_serial_sequence(\'blog_post\',\'id\'),
coalesce(max("id"), 1), max("id") IS NOT null) FROM "blog_post";',
 'SELECT setval(pg_get_serial_sequence(\'blog_post\',\'id\'),
coalesce(max("id"), 1), max("id") IS NOT null) FROM "blog_tag";']

As you can see, the problem is in the last "SELECT". Postgres backend
"thinks" that Post.tags is m2m relation with usual m2m sql table and
tries to update it's pk sequence. The table is of course non existant
and it resets sequence to max(, this is obviously
incorrect behaviour and results with potential DatabaseErrors
duplicate key on blog_post table.
Removing Post.tags and accessing related tags directly works as a
workaround, but not very nice and comfotable one..

Attachments (1)

13941.patch (3.5 KB) - added by ales_zoulek 5 years ago.
patch and tests

Download all attachments as: .zip

Change History (5)

comment:1 Changed 5 years ago by ales_zoulek

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

Changed 5 years ago by ales_zoulek

patch and tests

comment:2 Changed 5 years ago by ales_zoulek

  • Has patch set

comment:3 Changed 5 years ago by jbronn

  • Owner changed from nobody to jbronn
  • Status changed from new to assigned

I've confirmed this as a bug. See also #13821.

comment:4 Changed 5 years ago by russellm

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

(In [13449]) Fixed #13941 -- Corrected the way sequence names are reset under Postgres, especially when generic foreign keys are involved. Thanks to Ales Zoulek for the report and patch.

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