1

I'm trying to take a list of JSON objects, turn them into Python dicts, then populate the Concert model with an object for each of the Python dicts.

import json
from models import Concert
with open('output.json') as f:
    data = json.load(f)
for concert in data:
    Concert.objects.create(**concert)

I'm getting an error message I haven't seen before:

ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Is this something that can be easily addressed? There is a foreign key in my model that corresponds to one of the key-value pairs in the JSON objects; is that relevant to this error?

1
  • 1
    How do you exeute this? Just some file somewhere? Typically you use a custom command for this, so that Django is first loaded. The problem is probably that by running the file, you do not load the settings. Commented Jun 11, 2018 at 18:01

1 Answer 1

5

This is a common error, if you write an independent python file and execute it.

Defining a custom command

Although you can make sure the Django framework is properly loaded, usually the idea is that you define a custom command [doc].

So in your file structure, if app is the application where your Concert is located, you can construct directories and files (here listed in boldface):

someapp/
    management/
        __init__.py
        commands/
            __init__.py
            load_concerts.py
    __init__.py
    models.py
    views.py

Where the __init__.py files are empty. Then your load_concerts.py can look like:

from django.core.management.base import BaseCommand, CommandError
import json
from app.models import Concert

class Command(BaseCommand):
    help = 'Load JSON concert data'

    def add_arguments(self, parser):
        parser.add_argument('concert_file', type=str)

    def handle(self, *args, **options):
        with open(options['concert_file']) as f:
            data = json.load(f)
        for concert in data:
            Concert.objects.create(**concert)

You can the execute the command with:

$ manage.py load_concerts output.json --settings=my_settings

So just like you run the server (well you can see this as a builtin command), you can thus add specific commands).

By defining the filename as a parameter, we can easily load any .json file we want.

An independent Python program

You can define a loose Python file. In that case you need to load the settings, with:

from django.conf import settings
from projectroot import settings as projectsettings
settings.configure(projectsettings)

import django
django.setup()

import json
from app.models import Concert

with open('output.json') as f:
    data = json.load(f)
for concert in data:
    Concert.objects.create(**concert)

Then you can set the PYTHONPATH to the project root, and thus load the specific settings, but I think this will probably result in more pain that to define a command you can easily reuse.

Sign up to request clarification or add additional context in comments.

8 Comments

This is a really fantastic and thorough explanation and I greatly appreciate the time you took to draft it. I'm getting an ImportError: No module named management.commands.load_concerts. Most of my googling leads me to believe this is a problem with my init.py file missing or being named wrong, but I have checked and double-checked this question. Could it be anything else?
Of course! I edited my response with an error I'm getting after you submitted your reply. Any ideas what the problem might be?
@Danny: argh, you probably should add an __init__.py file at the management level as well, sorry, will edit.
Ah, perfect. No need to be sorry at all. I appreciate your time. Now I'm getting an IOError: No such file or directory: 'output.json'. The file is in the same directory as the load_concerts.py file. I'm guessing I need to poke around in the settings to load from here? Or maybe I can put these files elsewhere?
Ah, then the path should be something like someapp/management/commands/output.json (with someapp the name of the app). The paths are relative to the location where you call the script from.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.