【问题标题】:Import fails with KeyError: 'id'导入失败并出现 KeyError: 'id'
【发布时间】:2020-10-07 17:19:39
【问题描述】:

我正在尝试使用 foreignKey 将包含一些数据的 excel 文件导入模型,但我得到了 KeyError: 'id'

我已成功导出数据并导入相同的导出文件,当我将新数据添加到同一文件时,问题出现了。

进口:

此导入器将导入以下字段:名称、Brand__BrandName、性别、stockPrice

要导入的文件: 格式: xlsx 错误 行号:1 - 'id' p3,B1,男女皆宜,99999

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 639, in import_row
instance, new = self.get_or_init_instance(instance_loader, row)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 334, in get_or_init_instance
instance = self.get_instance(instance_loader, row)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 321, in get_instance
import_id_fields = [
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 322, in <listcomp>
self.fields[f] for f in self.get_import_id_fields()
KeyError: 'id'

行号:2 - 'id' p2, b2, 男女通用, 99999

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 639, in import_row
instance, new = self.get_or_init_instance(instance_loader, row)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 334, in get_or_init_instance
instance = self.get_instance(instance_loader, row)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 321, in get_instance
import_id_fields = [
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/import_export/resources.py", line 322, in <listcomp>
self.fields[f] for f in self.get_import_id_fields()
KeyError: 'id'

我的模特:

    from django.db import models
    from django.utils import timezone
    from django.conf import settings
    
 
    class Brand(models.Model):
       
        BrandName= models.CharField(max_length=40)
         
      
        def __str__(self):
             return self.BrandName
    
    
    
    
    class Perfume(models.Model):
        
        genderChoice = (
            ('unisex','unisex'), ('male', 'male'), ('female', 'female'))
             
        name = models.CharField(max_length=50)
        Brand= models.ForeignKey(to=Brand,on_delete=models.CASCADE, blank=False)
    
        gender = models.CharField(max_length=7, choices=genderChoice, default='unisex')
        
        description = models.TextField()
        stockPrice = models.IntegerField(default=99999)
    
        active = models.BooleanField(default=False)
        show_for_consumer = models.BooleanField(default=False) 
        created = models.DateField()
        author =models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
      
       
    
        def __str__(self):
            return self.name        
    
    
    class Pricing(models.Model):
        product =models.ForeignKey(Perfume, on_delete=models.CASCADE,related_name='prices')
        
        
         
        price= models.IntegerField()
        volume= models.IntegerField()
        def __str__(self):
             return 'Perfume {} - Price{} - Volume {}'.format(self.product.name,self.price, self.volume)

我的管理员.py

    from django.contrib import admin
    from .models import Perfume, Brand, Pricing
    from import_export.admin import ImportExportModelAdmin
    from import_export import resources, fields
    from import_export.widgets import ForeignKeyWidget
    
    # Register your models here.
    
    class PriceInline(admin.StackedInline):
        model = Pricing
    
    
        
    class ModelInline(admin.StackedInline):
        model = Perfume
    class BrandAdmin(admin.ModelAdmin):
        model = Brand
        inlines = [ModelInline,]
    
    #for import settings
    class ProductResorce(resources.ModelResource):
    
                          
     
        class Meta:
           
            model = Perfume
            exclude = ('active', 'show_for_consumer', 'created', 'author')
            fields=('name', 'Brand__BrandName', 'gender', 'stockPrice')
            export_order = ('name', 'Brand__BrandName', 'gender', 'stockPrice')
    #showing in product add

    class ProductImportAdmin(ImportExportModelAdmin):
    
        resource_class = ProductResorce
        list_display = ['name', 'gender', 'Brand']
        fields = ['name', 'gender', 'Brand', 'author', 'created', 'stockPrice', 'description']
        
        inlines = [PriceInline]
        
    
    
    admin.site.register(Brand, BrandAdmin)
    admin.site.register(Perfume, ProductImportAdmin)

exported file

【问题讨论】:

    标签: python-3.x django-import-export


    【解决方案1】:

    问题是当您第二次导入文件时,导入过程会尝试将每一行与数据库中的现有记录进行匹配,并尝试更新存储的数据。

    默认情况下,它将使用一个名为“id”的字段来执行此操作 (docs)。

    但是,您的数据集或资源 (ProductResorce) 中没有名为“id”的字段,因此会引发您看到的错误。

    要修复它,您应该添加一个唯一标识每个条目的字段,并在资源上声明它。例如,如果您使用名为“sku”的字段,则可以在资源上声明它:

    class ProductResource(resources.ModelResource):
      class Meta:         
        model = Perfume
        import_id_fields = ('sku',)
    

    您可以使用多个字段作为唯一标识符。

    拥有唯一标识符非常有用,因为这意味着您可以安全地重新运行作业,而不会出现失败或创建重复的风险。

    【讨论】:

    • 谢谢马修,当我尝试你的建议时,它会抛出一个新错误:“django.db.utils.IntegrityError: NOT NULL constraint failed: product_perfume.created”有什么想法吗?跨度>
    • 您的“创建”字段为空,数据库不允许这样做。在导入中提供“创建”日期时间值,或使用 auto_now_add 属性
    • 如果解决了您的问题,请将答案标记为“已接受”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2011-03-26
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多