django.db.utils.IntegrityError:重复的键值违反了唯一约束

时间:2019-02-28 12:36:40

标签: django django-models

我有国家(地区)模型

from django.db import models 

class Country(models.Model):
    country = models.CharField(max_length = 20, primary_key=True)
    country_id = models.IntegerField()

我使用以下自定义管理命令在“国家/地区”表中上传了一些数据

from django.core.management.base import BaseCommand, CommandError
from data.models import Country
import json
from .extract_country import extracting



get_parsed_json = extracting() 

def store_data():
    for key, value in get_parsed_json['api']['countries'].items():
        country_id_field = key
        country_name = value 
        One_country = Country.objects.create(country_id = country_id_field , country = country_name)
        One_country.save()
        print(One_country)



class Command(BaseCommand):
    def handle(self, **options):
        extracting()
        store_data() 

现在,我尝试将包含相同国家和另一个国家的扩展数据上传到“国家/地区”表,但是当我尝试上传数据时,出现以下错误。这是我的完整回溯

Traceback (most recent call last):
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 85, in _execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: duplicate key value violates unique constraint "data_co
untry_name_04df4fc7_uniq"
DETAIL:  Key (country)=(Algeria) already exists.


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\core\management\
__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "D:\Python\my_projects\forecast\lib\site-packages\django\core\management\
__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\core\management\
base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\core\management\
base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "D:\Python\my_projects\forecast\project\forecasting\data\management\comma
nds\upload_country.py", line 23, in handle
    store_data()
  File "D:\Python\my_projects\forecast\project\forecasting\data\management\comma
nds\upload_country.py", line 14, in store_data
    One_country = Country.objects.create(country_id = country_id_field , country
 = country_name)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\manage
r.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\query.
py", line 413, in create
    obj.save(force_insert=True, using=self.db)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\base.p
y", line 718, in save
    force_update=force_update, update_fields=update_fields)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\base.p
y", line 748, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, upda
te_fields)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\base.p
y", line 831, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\base.p
y", line 869, in _do_insert
    using=using, raw=raw)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\manage
r.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\query.
py", line 1136, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\models\sql\co
mpiler.py", line 1289, in execute_sql
    cursor.execute(sql, params)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 100, in execute
    return super().execute(sql, params)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._e
xecute)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\utils.py", li
ne 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "D:\Python\my_projects\forecast\lib\site-packages\django\db\backends\util
s.py", line 85, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "
data_country_name_04df4fc7_uniq"
DETAIL:  Key (country)=(Algeria) already exists.

我发现这对于django用户来说是非常常见的问题,但是没有找到解决方法。有什么建议么 ?

2 个答案:

答案 0 :(得分:0)

似乎您尝试使用与其主键相同的名称County创建county。 尝试使用get_or_create()

def store_data():
    for key, value in get_parsed_json['api']['countries'].items():
        country_id_field = key
        country_name = value 
        one_country, created = Country.objects.update_or_create(
            country_id=country_id_field
            defaults={'country': country_name},
        )
        # one_country.save() <- no need to save after create or get_or_create method.
        print(one_country)

答案 1 :(得分:0)

主键必须是唯一的,如果已经存在一个键为“阿尔及利亚”的实例,则无法创建另一个具有相同键的实例。

代替:

One_country = Country.objects.create(country_id = country_id_field , country = country_name)

您可以使用get_or_create

# ...
One_country, created = Country.objects.get_or_create(country=country_name)
One_country.country_id = country_id_field
One_country.save()
# ...