Thomas.Q
Thomas.Q

Reputation: 477

How can I connect to MySQL on Heroku?

I have a Django project that uses MySQL as its database. On my development machine the MySQL database runs on my local machine as shown here:

DATABASES = {

    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xxx',
        'USER': 'root',
        'PASSWORD': 'xxxx',
        'HOST': 'localhost',
        #'PORT': '3306',
    }
}

I have successfully deployed the project to Heroku, but it keeps showing that

2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)

since the setting is the local MySQL and the views.py contain functions that import local database. I still cannot figure out how to have the website to connect to this database.

Is there a way to make this work with Heroku, or do I need to find another host?

Upvotes: 1

Views: 6442

Answers (3)

Chris
Chris

Reputation: 136948

juanmhidalgo's answer is a good start, and can be generalized for arbitrary environment variables. But if you only care about the database variable there's another solution.

By default, Heroku provides a PostgreSQL database and sets your application's DATABASE_URL with a connection string that can be used to connect to it.

As far as I know, the various MySQL addons also set this variable but it would be helpful to know which one you've selected so we can confirm. It may need to be set manually, based on another environment variable.

Assuming that the DATABASE_URL environment variable is properly set you can use dj-database-url to set your database up directly, optionally providing a fallback to use when the variable isn't available (e.g. on your development box), in your settings.py file:

import dj_database_url

DATABASES['default'] = dj_database_url.config(
    default='mysql://root:<password>@localhost:3306/<database>',
)

Upvotes: 2

juanmhidalgo
juanmhidalgo

Reputation: 1546

A really useful way to do this is to use django-environ and set the configuration option on the heroku settings.

# settings.py
# Parse database connection url strings like psql://user:[email protected]:8458/db
DATABASES = {
    # read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
    'default': env.db(),

}

and your environment variable like:

DATABASE_URL=mysql://user:%[email protected]:3306/dbname

Regarding your question, Heroku is a really good option to deploy your projects.

Upvotes: 1

Karim N Gorjux
Karim N Gorjux

Reputation: 3033

You can promote the settings.py to a package. Create the settings folder like this one

settings/
├── __init__.py
├── base.py
├── dev.py
├── heroku.py

Keep the base.py as your settings.py and then, based on the env, changes what you need.

Your heroku.py could be

from .base import *

DATABASE = {
    # change to use the database on heroku
}

What is important is to tell the deploy version to use the new settings. Check the wsgi.py

import os

from django.core.wsgi import get_wsgi_application

# point to the new settings.dev as default, if the `DJANGO_SETTINGS_MODULE`
# is not set
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.dev")
application = get_wsgi_application()

Remember to change the DJANGO_SETTINGS_MODULE in heroku to settings.heroku

Upvotes: 1

Related Questions