Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django. South. Heroku. KeyError: 'default'

I'm new to Heroku, so I tried following the instructions literally and I'm lost with this error. So, when I included the settings.py configurations written in "Getting Started with Django on Heroku" I can't run the local server anymore unless I comment out South from my Installed Apps.

This is the error:

 from south.db import DEFAULT_DB_ALIAS
 File "/home/alejandro/Proyectos/olenv/local/lib/python2.7/site-packages/south/db/__init__.py", line 83, in <module>
 db = dbs[DEFAULT_DB_ALIAS]
 KeyError: 'default'

This is the relevant settings in settings.py:

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'dbolib',
    'USER': 'alejandro',
    'PASSWORD': 'zzzzz'
}
}

 # --- HEROKU --- #
 # Parse database configuration from $DATABASE_URL
 import dj_database_url
 DATABASES['default'] = dj_database_url.config()

Maybe it is supposed to be this way since South is a tool for production and therefore it conflicts with Heroku. Maybe not, since Im new to Heroku, any clarification will help.

Edit When I comment out South and try to run syncdb, I ge this error:

File "/home/alejandro/Proyectos/olenv/local/lib/python2.7/site-packages/django/db/backends/dummy/base.py", line 15, in complain
raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

requirements.txt:

Django==1.6
South==0.8.4
argparse==1.2.1
dj-database-url==0.3.0
dj-static==0.0.5
django-crispy-forms==1.4.0
django-debug-toolbar==1.2
django-endless-pagination==2.0
django-extensions==1.3.5
django-toolbelt==0.0.1
gunicorn==18.0
psycopg2==2.5.2
pystache==0.5.4
six==1.6.1
sqlparse==0.1.11
static==1.0.2
wsgiref==0.1.2
like image 220
Alejandro Veintimilla Avatar asked Mar 19 '23 11:03

Alejandro Veintimilla


1 Answers

When you comment out South in your INSTALLED_APPS, does it let you run python manage.py syncdb locally?

I think the problem is that you're overwriting your default database with your dj_database_url lines in your settings.py. When you're on Heroku, there's an environment variable named DATABASE_URL, which is what dj_database_url uses to config your database. However, if you don't have a similar environment variable locally, you won't be configuring your database correctly. The reason South is throwing an error is because it tries to connect to your database upon initialization (note how the error comes from South's __init__). If you tried to actually use your database locally after commenting out South, I'm guessing you'd get an error.

There are two ways to fix this. The first, and easiest, is to make a DATABASE_URL variable on your local machine. Given the settings you listed above, set your DATABASE_URL to 'postgres://alejandro:zzzzz@localhost/dbolib'. The second, and more difficult, is to add something in your settings to essentially check if you're on Heroku and, if not, skip over the dj_database_url configuration. Basically, nest your dj_database_url lines in your settings inside an if statement that would return True if on Heroku and False if not.

EDIT:

It gets a little messy, but if you want to keep it all in one file, you could do something like the following:

First, try to set your default database using dj_database_url. This means moving the following code ABOVE the DATABASES setting in your settings:

import dj_database_url
DATABASES = {}
DATABASES['default'] = dj_database_url.config()

This code sets your default database equal to the result from dj_database_url. However, there may not be a result. You'll want to test for this (which would indicate local development) and set a database accordingly. So, AFTER THE PREVIOUS CODE, add the following code:

if len(DATABASES['default']) == 0:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'dbolib',
            'USER': 'alejandro',
            'PASSWORD': 'zzzzz'
    }
}

This checks to see if you have anything in your DATABASES['default'] and, if not, sets your default database using your local settings.

This is a little messy, but it'll work. The better option may be to use different settings files, which adds another layer of complexity. Truly, the best option is to set your DATABASE_URL environment variable on all of your machines so that dj_database_url works as it should.

like image 174
Alex Avatar answered Mar 29 '23 01:03

Alex