Django Data import from JSON file to DB not working with OneToOneFields
I'm currently working on an importer which lets me import a json file from a folder which i get from another server. So far i can import all the regular fields of my model but the parts that are using OneToOneFields are not being imported. Instead i get this error message:
Something went wrong saving this Facility: Test Facility
Field 'id' expected a number but got {'PrimaryAddress': '1234 Test Avenue', 'SecondaryAddress': '', 'City': 'Testcity', 'RegionOrState': 'CA', 'PostalCode': '12345', 'Geolocation': ''}.
This is my code including the json i'm importing and the database model:
import os
import json
from data_import.models import Facility, FacilityAddress
from django.core.management.base import BaseCommand
from datetime import datetime
from jsontest.settings import BASE_DIR, STATIC_URL
class Command(BaseCommand):
def import_facility_from_file(self):
print(BASE_DIR)
data_folder = os.path.join(BASE_DIR, 'import_data', 'resources')
for data_file in os.listdir(data_folder):
with open(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
data = json.loads(data_file.read())
for key, data_object in data.items():
Name = data_object.get('Name', None)
IssuedNumber = data_object.get('IssuedNumber', None)
AddressInfo = data_object.get('AddressInfo', None)
try:
facility, created = Facility.objects.get_or_create(
Name=Name,
IssuedNumber=IssuedNumber,
AddressInfo=AddressInfo
)
if created:
facility.save()
display_format = "\Facility, {}, has been saved."
print(display_format.format(facility))
except Exception as ex:
print(str(ex))
msg = "\n\nSomething went wrong saving this Facility: {}\n{}".format(Name, str(ex))
print(msg)
def handle(self, *args, **options):
"""
Call the function to import data
"""
self.import_facility_from_file()
class FacilityAddress(models.Model):
PrimaryAddress = models.CharField(max_length=50, null=True, blank=True)
SecondaryAddress = models.CharField(max_length=50, null=True, blank=True)
City = models.CharField(max_length=50, null=True, blank=True)
RegionOrState = models.CharField(max_length=30, null=True, blank=True)
PostalCode = models.CharField(max_length=20, null=True, blank=True)
Geolocation = models.CharField(max_length=20, null=True, blank=True)
class Facility(models.Model):
UUID = models.CharField(max_length=20, null=True, blank=True)
Name = models.CharField(max_length=50, null=True, blank=True)
admin_uid = models.OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
AddressInfo = models.OneToOneField(FacilityAddress, null=True, blank=True, on_delete=models.SET_NULL)
IssuedNumber = models.CharField(max_length=20, null=True, blank=True)
mainimage = models.ImageField(null=True, blank=True)
Capacity = models.IntegerField(null=True, blank=True)
Licensee = models.CharField(max_length=30, null=True, blank=True)
Email = models.EmailField(max_length=30, null=True, blank=True)
AdministratorName = models.CharField(max_length=30, null=True, blank=True)
Status = models.CharField(max_length=10, null=True, blank=True)
TelephoneNumber = models.CharField(max_length=20, null=True, blank=True)
ClosedTimestamp = models.IntegerField(null=True, blank=True)
MostRecentLicenseTimestamp = models.IntegerField(null=True, blank=True)
InspectionInfo = models.OneToOneField(FacilityInspectionInfo, null=True, blank=True, on_delete=models.SET_NULL)
Complaints = models.OneToOneField(FacilityComplaints, null=True, blank=True, on_delete=models.SET_NULL)
{"00016ed7be4d872aseddsf6f36bfsdfd647f3eb41cadedd2130bdfsdfsdf6fbbbf24c2f1a64d2cf34ac4e03aaa30309816f98a7389b2bb324a2":{"UUID":"00016ed7be4d872aseddsf6f36bfsdfd647f3eb41cadedd2130bdfsdfsdf6fbbbf24c2f1a64d2cf34ac4e03aaa30309816f98a7389b2bb324a2","Name":"SENIOR CARE","IssuedNumber":"123456","Licensee":"SENIOR CARE","Email":"test@dfjksdajfkljklsd.com","AdministratorName":"Tester","TelephoneNumber":"(123) 456-789101112","AddressInfo":{"PrimaryAddress":"123 Test Road","SecondaryAddress":"","City":"Testcity","RegionOrState":"TESTSTATE","PostalCode":"12345","Geolocation":"11.1111,-11.1111"},"Capacity":1,"MostRecentLicenseTimestamp":1234567891,"ClosedTimestamp":0,"InspectionInfo":{"ComplaintRelatedVisits":0,"InspectionRelatedVisits":0,"NumberOfVisits":0,"LastVisitTimestamp":0},"Complaints":{"ComplaintsTypeA":0,"ComplaintsTypeB":0,"SubstantiatedAllegations":0,"TotalAllegations":0}},
Does anyone know how i can fix this?
If you want to create both a Facility
and a FacilityAddress
, you need a get_or_create
statement for both of them. Then, you keep a variable for the created/retrieved FacilityAddress
, and you provide that to Facility
.
Example:
facility_address, address_created = FacilityAddress.objects.get_or_create(
PrimaryAddress=PrimaryAddress,
SecondaryAddress=SecondaryAddress,
City=City,
RegionOrState=RegionOrState,
PostalCode=PostalCode,
Geolocation=Geolocation
)
facility, facility_created = Facility.objects.get_or_create(
Name=Name,
IssuedNumber=IssuedNumber,
AddressInfo=facility_address
)
This code creates the facility address if it does not exist, and provides the object representing that address to the second get_or_create
.
Side note: AddressInfo
should probably be a ForiegnKey
, not a OneToOneField
, unless it is impossible for two facilities to exist at the same address.