Search code examples
pythondjangopostgresqldjango-modelsdjango-import-export

Django Import-Export Import Duplicate key value violates Error


I'm working on a project with Django 1.10, Python 3.6 and PostgreSQL as the database backend, in which I have a model called 'Article" and I need to import data from CSV files. I have imported my first CSV file successfully with the following fields: id, link & category It's ID fields starts from 1 to 1960 then in next file, I have started ID field from 1961 to onward but it shows the following error:

Line number: 1961 - duplicate key value violates unique constraint "article_article_pkey" DETAIL: Key (id)=(1961) already exists.

Even when i see my Article model in Django admin it shows IDs from 1- 1960

Here's my models.py:

class Article(models.Model):
   id = models.AutoField(primary_key=True)
   link = models.URLField(max_length=255)
   category = models.CharField(max_length=255, choices=Categories)

Here's admin.py

@admin.register(Article)
    class ArticleAdmin(ImportExportModelAdmin):
    resource_class = views.ArticleResource
    readonly_fields = ('id',)

Solution

  • I have triggered that what's the issue : Actually, the problem is PostgreSQL primary key sequential which is not synced with table rows. That's why, when I insert a new row I get a duplicate key error because the sequence implied in the serial datatype returns a number that already exists.

    To solve this issue we have to reset the ID sequential for PostgreSQL, Here's the step by step guide:

    1. Log onto the DB shell and connect to your database
    2. First, check maximum value for id column of your table as SELECT MAX(id) FROM your_table;
    3. Then, check what's going to be the next value for ID as : SELECT nextval('your_table_id_seq');
    4. If nextval is the next number of Max value then it's right. e.g MAX=10 & nextval=11
    5. Otherwise reset the id_seq for your table as:

      BEGIN;

      -- protect against concurrent inserts while you update the counter

      LOCK TABLE your_table IN EXCLUSIVE MODE;

      -- Update the sequence

      SELECT setval('your_table_id_seq', COALESCE((SELECT MAX(id)+1 FROM your_table), 1), false);

      COMMIT;