Django导入导出-唯一约束失败

6

我正在遵循这份文档,学习如何使用django-import-export:

https://django-import-export.readthedocs.io/en/latest/getting_started.html#declaring-fields


我有一个看起来像下面这样的Excel表格:

enter image description here


我想将这些数据存储在这个模型中:

class ExcelData(models.Model):
    var1 = models.CharField(max_length=200)
    var2 = models.CharField(max_length=200,unique=True)
    var3 = models.CharField(max_length=200)
    var4 = models.CharField(max_length=200)

这是我目前为止的进展:
@admin.register(ExcelData)
class ViewAdmin(ImportExportModelAdmin):
    exclude = ('id',)

class ExcelDataResource(resources.ModelResource):
    var1 = Field(attribute='var1', column_name='Name')
    var2 = Field(attribute='var2', column_name='SAP_ID')
    var3 = Field(attribute='var3', column_name='Abbreviation')
    var4 = Field(attribute='var4', column_name='Max. Capa')

    class Meta:
        model = ExcelData
        import_id_fields = ('var2',)
        exclude = ('id',)

这是我得到的内容:
这是图片链接:enter image description here 下面是CSV文件链接:http://www.sharecsv.com/s/9d1112392cd7f10378de7fc0811dd0c9/REAL_CSV_SIMPLE.csv 当我尝试导入多行时,如下图所示: enter image description here,我收到了以下错误信息:
Line number: 2 - UNIQUE constraint failed: myapp_exceldata.var2
b, e, h, k
Traceback (most recent call last):
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: myapp_exceldata.var2

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

Traceback (most recent call last):
File "D:\Users\...\env\lib\site-packages\import_export\resources.py", line 527, in import_row
self.save_instance(instance, using_transactions, dry_run)
File "D:\Users\...\env\lib\site-packages\import_export\resources.py", line 320, in save_instance
instance.save()
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 746, in save
force_update=force_update, update_fields=update_fields)
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 784, in save_base
force_update, using, update_fields,
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 887, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 926, in _do_insert
using=using, raw=raw,
File "D:\Users\...\env\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\Users\...\env\lib\site-packages\django\db\models\query.py", line 1204, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "D:\Users\...\env\lib\site-packages\django\db\models\sql\compiler.py", line 1384, in execute_sql
cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: myapp_exceldata.var2

Line number: 3 - UNIQUE constraint failed: myapp_exceldata.var2
c, f, i, l
Traceback (most recent call last):
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: myapp_exceldata.var2

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

Traceback (most recent call last):
File "D:\Users\...\env\lib\site-packages\import_export\resources.py", line 527, in import_row
self.save_instance(instance, using_transactions, dry_run)
File "D:\Users\...\env\lib\site-packages\import_export\resources.py", line 320, in save_instance
instance.save()
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 746, in save
force_update=force_update, update_fields=update_fields)
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 784, in save_base
force_update, using, update_fields,
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 887, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "D:\Users\...\env\lib\site-packages\django\db\models\base.py", line 926, in _do_insert
using=using, raw=raw,
File "D:\Users\...\env\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\Users\...\env\lib\site-packages\django\db\models\query.py", line 1204, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "D:\Users\...\env\lib\site-packages\django\db\models\sql\compiler.py", line 1384, in execute_sql
cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "D:\Users\...\env\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "D:\Users\...\env\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: myapp_exceldata.var2

以下是CSV文件:

http://www.sharecsv.com/s/3f09eb14f7916933604481fd999d03db/REAL_CSV_FULL.csv


感谢您提供任何建议。


1
它在var4上给出了唯一约束错误,但在您的模型中并不唯一。这是不可能的。 - dirkgroten
你尝试导入的数据不是唯一的。你有两行最大容量为5。 - dirkgroten
这意味着您正在导入一行具有该列空值的数据。 - dirkgroten
我已将数据复制到新的Excel表中。没有空值。仍然出现相同的错误。 - user12660805
CSV文件出现相同的错误。 - user12660805
显示剩余9条评论
1个回答

1
导入的工作方式如下:
  • 您需要一个唯一标识符,以便在导入时,导入-导出模块“知道”它是否需要创建新行还是修改现有行。
  • 如果该唯一标识符不是模型的id字段(在您的情况下是自动递增的行号),那么它必须是其他唯一字段。根据您当前定义的模型,var1...var4字段中没有一个被声明为唯一的,因此无法导入。
  • 如果多个“id字段”组合在一起是唯一的,则可以使用多个“id字段”,但这也不是您的模型的情况。
  • 导入模块实际上会在数据库上执行get_or_create()调用,使用unique_id_fields作为获取参数。如果它返回多个行,导入将崩溃。

为了给您一个想法,并假设SAP_ID是唯一标识符(我怀疑Max. Capacity不是,名称并不表明它是),这应该是您的模型:

class ExcelData(models.Model):
    var1 = models.CharField(max_length=200)
    var2 = models.CharField(max_length=200, unique=True)
    var3 = models.CharField(max_length=200)
    var4 = models.CharField(max_length=200)

注意,您的模型还具有隐式字段id,导入和导出功能已知该字段,您需要决定如何处理它,因为它不在您的导入数据中。这就是为什么您会收到您提到的错误,因为它是您的模型中的一个字段,您尚未分配给任何内容。最好将其排除在外,因为它在此处不相关(如果行尚不存在,Django将自动递增新的id,例如当您使用ExcelData.objects.create()创建模型时)。
class ExcelDataResource(resources.ModelResource):
    var1 = Field(attribute='var1', column_name='Name')
    var2 = Field(attribute='var2', column_name='SAP_ID')
    var3 = Field(attribute='var3', column_name='Abbreviation')
    var4 = Field(attribute='var4', column_name='Max. Capa')

    class Meta:
        model = ExcelData
        import_id_fields = ('var2',)
        exclude = ('id',)

使用这段代码和下面的csv文件,它可以正常工作,我已经测试过了:

Name,SAP_ID,Abbreviation,Max. Capa
a,d,g,j
b,e,h,k
c,f,i,l

尝试第二次导入或数据库中已存在值为d、e或f的var2数据时,将会出现exceldata.var2的UNIQUE约束失败错误。注意:如果Max. Capa确实是您的唯一id字段,则不应将其分配给var4而是分配给id。这也可以工作,尽管如上所述,我怀疑这是否是您想要的行为。 更新/注释2:在Django-import-export中存在一个bug,当您尝试更新现有数据时,它会导致唯一约束异常:如果您的unique_id_field与您导入的数据中的column_name名称不同(例如SAP_IDvar2),并且您尝试重新导入包含具有相同id的已存在行的数据(例如,因为您想要更改其他值),则应该更新该行,但当前会引发异常。这不能解释var4上的异常(这是因为您还将var4设置为唯一的,如果您导入具有重复var4Max. Capa)值的不同行,则也会收到异常)。

是的,我确实排除了“id”。根据我的帖子:“错误明确指出,即使将import_id_fields设置为其他内容,import_export模块仍在寻找名为'id'的列” - user12660805
import_id_fields与您的错误关系不大,您的错误是说模型的id字段没有映射到任何内容。import_id_fields并不告诉哪个列要映射到id字段,它告诉哪些列用作唯一标识符。这就是为什么您需要在Meta中添加exclude = ('id', )。我已经阅读了您的帖子。 - dirkgroten
我已经将var2保留为唯一值并重新构建了数据库,但仍然出现相同的错误。 - user12660805
无法重现(请查看我的更新),请确保您文件中的列名与导入资源中的列名相对应。并且请确保文件末尾没有空行,您的CSV文件包含一个空行。如果更改了模型的唯一属性,请确保进行迁移/迁移。 - dirkgroten
我不理解这个问题。如果不同的导入具有不同的列,则它们应该是不同的模型。 - dirkgroten
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接