将带有外键的CSV文件上传到Django

时间:2019-03-04 14:18:19

标签: python django django-models

我已经上传了两个数据集(没有基于Service和Library模型的外键,请参阅下文),但是无法上传第三个具有其他两个数据集的外键的数据集。

首先,通过在“ python manage.py shell”中运行此代码,将它们上传到Shell中。我的外键列是服务和库,并通过“ cpt”连接到服务,并通过“ hid”连接到库。

这些是代码不起作用的部分

service=Service.objects.get(cpt=row['cpt']), 
library=Library.objects.get(hid=row['hid'])

这是完整的代码:

from catalog.models import Service, Library, Price
# not including the intro - price dataset gets pulled in
with open('price.csv') as csvfile:
      reader = csv.DictReader(csvfile)                             
      for row in reader:                                                                  
            p = Price(com_desc=row['com_desc'],service=Service.objects.get(cpt=row['cpt']),price_offer=row['price_offer'], comments=row['comments'], library=Library.objects.get[hid='hid'])
            p.save()

这是我得到(更新)的错误:

 site-packages/django/db/models/query.py", line 399, in get
    self.model._meta.object_name
catalog.models.Service.DoesNotExist: Service matching query does not exist.

这是我的模型:服务,图书馆和价格。就像我之前说的,服务和库已经上载,但是由于外键的缘故,很难上载Price。

# Service Model
class Service(models.Model):
    serviceid = models.UUIDField(default=uuid.uuid4, help_text='Unique ID for this particular service in database')
    desc_us = models.TextField(blank=True, primary_key = True)
    cpt = models.IntegerField(default= 10000)
    price_std = models.DecimalField(max_digits=6, decimal_places=2, blank=True)

# Library Model
class Library(models.Model):
    hid = models.CharField(max_length = 8, null=True)
    name = models.CharField(max_length=200, primary_key=True)
    hopid = models.UUIDField(default=uuid.uuid4, help_text='Unique ID for this particular hospital in database')
    address = models.CharField(max_length = 200, null = True)
    city = models.CharField(max_length = 50, null = True)
    state = models.CharField(max_length = 2, null=True)
    zipcode = models.CharField(max_length = 5, null=True)
    phone = models.CharField(max_length = 12, null=True)

# Price Model, Foreign Keys are; Service, Library (want to connect these by 'cpt' for service and 'hid' for library)
class Price(models.Model):
  priceid = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular service in database')
  com_desc = models.CharField(max_length = 200, blank = True, null = True)
  service = models.ForeignKey("Service", on_delete=models.SET_NULL, null=True)
  price_offer = models.DecimalField(max_digits=8, decimal_places=2, blank=True)
  comments = models.CharField(max_length = 200, blank = True, null =True)
  library = models.ForeignKey("Library", on_delete=models.SET_NULL, null=True)

对price.csv中的行进行采样

enter image description here

1 个答案:

答案 0 :(得分:1)

此行显然太紧凑,无法调试;尝试将其分解:

p = Price(com_desc=row['com_desc'],service=Service.objects.get(row['cpt']),price_offer=row['price_offer'], comments=row['comments'], library=Library.objects.get['hid'])

一件引人注目的事情是,你可能是这个意思:

library=Library.objects.get(row['hid'])  # rather than .get['hid']

除此之外,在创建并尝试保存新的Price对象之前,我将分别创建并打印出各个字段以确保它们包含您期望的内容。

========

如果实际上每个Service只有一个cpt和一个Library只有一个hid,那么使用get()是可以的。但是,您应该通过在相关的模型字段中添加unique constraint来形式化(如果在添加约束时出现错误,那么值毕竟不是唯一的。)

如果有多个选择哪个都没有关系,则可以使用以下方法:

service = Service.objects.filter(row['cpt'])[0]

请注意,如果找不到给定cpt的记录,则会引发错误(但是如果找不到匹配的对象,get()也会出错)。

您可以对Libraryhid进行同样的操作。