How can I connect to MySQL on Heroku? - python

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?

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>',
)

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

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:pass#127.0.0.1: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:%23password#127.0.0.1:3306/dbname
Regarding your question, Heroku is a really good option to deploy your projects.

Related

Django not syncing with sqlite3 (official polls tutorial)

So I'm following the official tutorial (creating a polls app) for django and I'm having db issues. For some reason I didn't have sqlite3 included with python (not a big issue, I just installed it). After installation, I have a connection in settings.py like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
I ran python migrate.py migrate. The next step was to run sqlite3 and do this:
.schema
Nothing shows up, because no DB exists. I'm very confused as to what I may not be doing right (or what I have done to mess it up) to get a proper database connection for the app.
sqlite is a file-based db, so you need to tell it what database file to open. Either do it explicitly:
sqlite3 path/to/db.sqlite3
or, better, use Django's shortcut:
./manage.py dbshell

django - error adding database to heroku

I am struggling to deploy my app on heroku. Mainly due to database configuration.
This is the bottom of the settings.py file,
import dj_database_url
DATABASES = { 'default': dj_database_url.config() }
try:
from .local_settings import *
except ImportError:
pass
This is my local_settings.py file,
import os
BASE_DIR = os.path.dirname(os.path.dirname(file))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'test',
'USER': 'test',
'PASSWORD': 'postgres',
'HOST': 'localhost',
'PORT': 5432,
}
}
I can run heroku local web successfuly.
But when I run , heroku run python manage.py migrate, it gives me error,
django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
When I run, heroku run python manage.py shell,
And then run
>>> import dj_database_url
>>> dj_database_url.config()
I get the dictionary giving me the full information about the database.
Where is the issue ?
Your local_settings file should not be deployed. It is for local use only, hence the name. You should exclude it from your git repo.
Try importing the settings from local_settings.py first, then change the DATABASES setting,
import dj_database_url
try:
from .local_settings import *
except ImportError:
pass
DATABASES = { 'default': dj_database_url.config() }
You have defined a DATABASES variable in the file, but when you are importing the local_settings.py, your DATABASES configuration is being overridden by the development values. You should do the import first and then change the DATABASES option.
Personally, I'd suggest that you should keep a base_settings.py to contain every settings other than databases, then import the same into the heroku_settings.py, rather than importing the whole local_settings.
Keeping a base_settings, development_settings, heroku_settings(or production_settings) would make it easier to handle the deployment.

Django psycopg2.OperationalError: fe_sendauth error but not connecting to postgresql database

I am using the following sqlite connection in my myapp/settings.py file:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':testdb:',
#I also tried 'NAME': 'testdb',
},
}
in my manage.py file I am using:
if __name__ == "__main__":
os.environ.setdefault("myapp.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
On running ./manage.py migrate on the command line I get the following error:
django.db.utils.OperationalError: fe_sendauth: no password supplied
I tried removing psycopg2 and re-ran the migration and get the following error:
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: No module named 'psycopg2'
I can't work out why django is trying to connect to a psql database where the only DATABSES configuration in the application is for sqlite3.
Could this be due to a dependency?
Django only uses DATABASES setting to generate migrations using a specific database driver. I believe somewhere, there is an import which is overriding your DATABASES setting. These are possible places to look for debugging in order of priority.
Any import into settings.py file after you set DATABASES variable which might override it.
if above is not the case, Some dependency must be overriding this setting manually. you might want to look into your INSTALLED_APPS.
If still not enough, you might need to look at any other dependency that you are using in your project which tries to interact with django.
Try this,
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
This might be helpful for you.

Django on Google AppEngine with CloudSQL: How to connect database (Error 2002, Can't connect to local MySQL server..)

I'm trying to start a Django app to be hosted on GAE, using CloudSQL. Locally, I'm on Mac OSX Maverics, working within a virtualenv (via virtualenvwrapper).
After installing the GAE SDK for Python, I started my virtual environment, installed Django 1.5 from /usr/local/google_appengine/lib/django-1.5/
Also, on appengine.google.com I created a new app, and connected a CloudSQL instance to it (enable billing).
I'm able to create a new Django project, e.g. django-admin.py startproject test01, then I edit its settings.py to change the DATABASES definition per Google's instructions, e.g:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '/cloudsql/myapp-test01:myapp-db-test01',
'NAME': 'test01',
'USER': 'test01',
}
}
I also added app.yaml to the root of the project folder, per Google's docs:
application: test01
version: 1
runtime: python27
api_version: 1
threadsafe: true
libraries:
- name: django
version: "1.5"
builtins:
- django_wsgi: on
This is where I hit roadblocks.
First: What exactly should be entered into the DATABASES for NAME and USER fields? The docs do not go into any detail.
Second, when I run: python manage.py syncdb to initialize the app, I get:
OperationalError: (2002, "Can't connect to local MySQL server through socket '/cloudsql/desgn-test-01:db-test-01' (2)")
I do have MySQL installed, via brew install mysql (although I didn't do that inside the virtual environment), and I also have MySQL-python.
I'm new to GAE and fairly inexperienced with setting up databases, so I'm not sure what do try next. I'm not sure if the issue is with my local MySQL, or the CloudSQL connection settings?
(A more general Django on GAE question: What is the workflow exactly? If I get the connection to work, does it mean that I am using CloudSQL even when developing my Django app locally? How do I subsequently "push" the app to the AppEngine, or make updates? I'm assuming this is done with the Launcher but what is the correlation between creating (adding) an app using the appengine.google.com dashboard, versus adding a new app in the local launcher? Quite confused by this -- are these two one and the same app, need to have identical names, or..?)
Looks like at the time, you were missing the password field as well...
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test01',
'USER': 'test01',
'PASSWORD': '[password]',
'HOST': '/cloudsql/myapp-test01:myapp-db-test01',
'PORT': '3306',
}
Using the GUI for Cloud SQL, you can always add new Super Admin level users to the Cloud SQL instance in case you're unsure what user to use as well.

How to set up DJANGO with MAMP (mysql)?

I've been trying to set up my Django project with MAMP for hours,, but still having problem understanding what's going on..
So what I've been doing is:
-First, obviously I installed all the necessary packages (ex. mysql, mysql-python, etc)
-I changed the MAMP's Apache Document Root to Django project folder (/MyDjangoProjects/Sample_Project/)
-I changed the Sample_Project's setting.py to:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'samleprojectdb',
'USER': 'root',
'PASSWORD': 'password1',
'HOST': '/Applications/MAMP/tmp/mysql/mysql.sock',
'PORT': '',
}
}
-Finally, I ran the Apache and MySQL servers with MAMP and navigated localhost:8888
So I guess basically theses are all the necessary steps that I need to take...
I expected that navigating the page localhost:8888 will direct to my project's main page view (index.html), as I configured in urls.py. However, it just opens an "Index of /" page containing the directories and python files in my local directory. I know MAMP is intended to be used with PHP and to look for index.php, but I thought it should work with Django projects as well..
1. Is there something else I need to do to test Django projects with MAMP??? Thanks...
2. Also, where is the database file "sampleprojectdb" created???? When I used sqlite instead of mysql, the database file was automatically created in the project directory when I ran "python manage.py syncdb"
The host expects the address of the machine that runs the mysql server,like localhost or an IP of the system that runs the DB server.
Also,Use blank for localhost..
About where the database is created,if you mean the files,they are at /var/lib/mysql,but they wont be of much use.syncdb creates the database with the specified configuration.
Also, to run django with apache you will have to setup apache to run the wsgi daemon.
You can try your application using the development server by python manage.py runserver

Categories