Running two databases on heroku with django

I have two databases that my Django application needs access. One is a shared database owned by a separate app with the Django app only having read access. The second is entirely owned by the Django app.

For local development I am ok but I'm not sure how to configure things so that Heroku uses the second database.

Currently I have the shared database promoted to DATABASE_URL and the secondary database is at HEROKU_POSTGRESQL_BLUE_URL.

In my settings I have:

DATABASES = {  
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'main_database_name',
        'USER': 'username',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    }, 'secondary': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME':  'secondary_database_name',                  
        'USER': 'username',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    } 
}

Please ask any more questions if you need me to clarify.

Thanks!

In summary, my specific problem is: I don't know how to have Heroku use the HEROKU_POSTGRESQL_BLUE_URL as the "secondary" database.

---Edit----

At the bottom of settings.py:

# Configure Django App for Heroku.
import django_heroku
django_heroku.settings(locals())

This is where the connection is made between my app's default database and Heroku's DATABASE_URL. I still haven't solved the issue but after some troubleshooting help in the comments, I believe the answer will be found in there.

1 answer

  • answered 2018-01-12 00:19 wuliwong

    Here is my working solution.

    I have a local_settings.py file not tracked by version control. This contains the database settings for the developer's postgres instance.

    local_settings.py

    DATABASES = {  
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'main_database_name',
            'USER': 'username',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': '5432',
        }, 'secondary': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME':  'secondary_database_name',
            'USER': 'username',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': '5432',
        }
    }
    

    Then in settings.py I try to import the local_settings.py file. If it doesn't exist, I use the django_heroku package to configure everything for Heroku. In my case, I need to pass the keyword argument databases=False since I want to do a more custom configuration for the databases.

    settings.py (only the relevant parts)

    # Database
    # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
    # These database settings are used for heroku deployments. They are overwritten with local_settings.py in development.
    DATABASES = {  
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('DATABASE_URL'),
            'USER': '',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': '5432',
        }, 'secondary': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('SECONDARY_DATABASE_URL'),
            'USER': '',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': '5432',
        }
    }
    
    
    try:
        from local_settings import *
    except ImportError as e:
        # Configure Django App for Heroku.
        import django_heroku
        django_heroku.settings(locals(), databases=False)
    

    In order for this to work you would need to set the Heroku env variable SECONDARY_DATABASE_NAME to the url of your database.

    To find out the URL of your secondary database run heroku config -a your_app_name. Copy the url and then set a new environment param in heroku by running

    heroku config:set SECONDARY_DATABASE_URL=postgres://xxxxxxx -a your_app_Name

    There are a lot of choices with how you would handle the ENV variables, I liked this because I can just set it in my staging and production environments and the same settings work for both.