user10931108
user10931108

Reputation:

Uploading a CSV file with foreign key into Django

I have uploaded two datasets (without foreign keys based on Service and Library models see below), but cannot upload the third which has foreign keys for the two other datasets.

First, I'm uploading them in the shell, by running this code in "python manage.py shell". My foreign key columns are service and library and connecting to service via 'cpt' and library via 'hid'.

These are the parts of the code not working

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

This is the full code:

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()

Here is the error that I get (updated):

 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.

Here are my models: Service, Library and Price. As I said before, Service and Library are already uploaded, but struggling to upload Price because of the foreign keys.

# 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)

Sample rows from price.csv

enter image description here

Upvotes: 1

Views: 781

Answers (1)

Endre Both
Endre Both

Reputation: 5730

This line is clearly too condensed for debugging; try breaking it up:

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'])

One thing that stands out is that you probably mean this:

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

Other than that, I'd create and print out the individual fields separately to make sure they contain what you expect, before creating and trying to save the new Price object.

========

If there really is always one and only one Service per cpt and only one Library per hid, then using get() is fine. You should however formalize that by adding a unique constraint to the relevant model fields (if you get an error on adding the constraint, then the values are not unique after all).

If it doesn't matter which one you select when there are several, you can use this:

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

Note that this will throw an error if no records are found for a given cpt (but then get() would error as well if no matching object is found).

You can do the same with Library and hid.

Upvotes: 1

Related Questions