Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate revision numbers causing IntegrityErrors #1

Open
kirku1g opened this issue Nov 22, 2012 · 0 comments
Open

Duplicate revision numbers causing IntegrityErrors #1

kirku1g opened this issue Nov 22, 2012 · 0 comments

Comments

@kirku1g
Copy link

kirku1g commented Nov 22, 2012

There are two ways duplicate revision numbers can be created, which causes the following error:

IntegrityError: duplicate key value violates unique constraint "fullhistory_fullhistory_revision_key"
DETAIL:  Key (revision, content_type_id, object_id)=(6869, 19, 1840) already exists.

The revision number is calculated in FullHistory.save():

if not self.pk:
    self.revision = len(FullHistory.objects.filter(content_type=self.content_type, object_id=self.object_id))
  1. If another FullHistory model is inserted into the database after the revision number has been calculated, but before inserting the current model.

  2. If old revisions are removed, for instance if your revision history becomes too large to store.

A solution for number 2 would be to find the maximum revision number and increment it:

max_revision = FullHistory.objects.filter(content_type=self.content_type, object_id=self.object_id).aggregate(rev=Max('revision'))['rev']
                self.revision = (max_revision + 1) if max_revision is not None else 0

The hacky solution currently employed for number 1 is to retry with a new revision number if an IntegrityError is raised.

Traceback of the error in case it helps:

File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 570, in save_base
    created=(not record_exists), raw=raw, using=using)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 172, in send
    response = receiver(signal=self, sender=sender, **named)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/fullhistory.py", line 124, in save_history_signal
    create_history(instance, created and 'C' or 'U')

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/fullhistory.py", line 79, in create_history
    fh.save()

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/fullhistory/models.py", line 187, in save
    return super(FullHistory, self).save(*args, **kwargs)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/base.py", line 553, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/manager.py", line 195, in _insert
    return insert_query(self.model, values, **kwargs)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/query.py", line 1436, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)

  File "/var/local/polaris/env/rest/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
    return self.cursor.execute(query, args)

IntegrityError: duplicate key value violates unique constraint "fullhistory_fullhistory_revision_key"
DETAIL:  Key (revision, content_type_id, object_id)=(6869, 19, 1840) already exists.

Side note: Passing a QuerySet into len will execute a query returning all matching rows. Using .count() translates into an SQL COUNT query and should be quicker.

Thanks for reading :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant