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.

Back to Top