Configuring a Django PostgreSQL project is a straight-forward process that involves updating the settings.py file and adding one additional library (psycopg2). Depending on which IDE, OS, and Python version used there are several possible errors that can arise. We’ll address those here as well.
Django comes configured to work with a local SQLite database by default, which is great for early-stage app development. Unfortunately, it’s not great for production use or even some more stringent development tasks like concurrent I/O. Below are the steps needed to configure a new Django project for use with a PostgreSQL database.
Django PostgreSQL Setup
Django uses some third-party libraries by default but does not install the required libraries to support postgres
. Here’s a look at the packages installed after a clean install of Django on a new virtual environment:
asgiref==3.3.1 Django==3.1.4 pytz==2020.4 sqlparse==0.4.1
Django is designed to use a project-folder sqlite
database by default that is configured in the project/project/settings.py and to use the django.db.backends.sqlite3
adapter as such:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
This tells Django to use a database named BASE_DIR/db.sqlite3
as the project’s database. To use a postgres
database, the following steps must happen:
- Specify the correct Django adapter + credentials for Postgres
- Install necessary 3rd party library for Postgres
- Specify credentials to new/existing postgres database
These steps are simple enough but can benefit from some elaboration.
Step 1: Specify Postgres Adapter + Credentials
To make Django work with Postgres, an adapter other than the default sqlite
adapter must be specified. I like working with the psycopg2
Postgres adaptor and have shown how to specify that adapter below:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': "db_name", 'USER': "db_username", 'PASSWORD': "db_password", 'HOST': "db_host", 'PORT': "db_port", # 5432 by default } }
In older versions of Django, the adapter was named django.db.backends.postgresql_psycopg2
. This was changed from release 1.9 forwards and summarized in the official release notes as such:
The PostgreSQL backend django.db.backends.postgresql_psycopg2
is also available as django.db.backends.postgresql
. The old name will continue to be available for backward compatibility.
Obviously, you need to have access to a Postgres database to make this work well. You should replace the values in the above code with the database to which your project will connect. Common values for HOST and PORT are localhost and 5432 respectively, which 5432 being the default Postgres port, as described in the official PostgreSQL documentation.
Step 2: Install Necessary Postgres Adaptor
While Django ships with an “adapter” for Postgres, it still needs a 3rd party library for support. If you simply add the code above and run python manage.py makemigrations
you’ll get a stacktrace with the following exception:
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: No module named 'psycopg2'
Django’s django.db.backends.postgresql
adaptor bridges Django’s own ORM models to Postgres, but doesn’t actually provide the adaptors needed for actual Postgres usage. Rather than re-inventing the wheel, the Django Project has elected to use the psycopg2 library—arguably the most popular python adapter for Postgres.
To make the Django adaptor work, the psycopg2 library needs to be installed with this command: pip install psycopg2
. Running the pip freeze command should now produce the following output:
asgiref==3.3.1 Django==3.1.4 psycopg2==2.8.6 pytz==2020.4 sqlparse==0.4.1
Common Issues with psycopg2
Depending on what platform, Python version, or IDE used; psycopg2 has some known-issues when it comes to installation. The most common is a DLL error that will prevent Django from creating the required migrations:
ImproperlyConfigured Exception
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: DLL load failed while importing _psycopg: The specified module could not be found.
This error indicates that a core DLL file is missing from the psycopg2 installation. It’s important to recognize that psychopg2 is a third-party library and, as such, may not always be compatible with the latest Python version. In some cases, reverting to a previous version of Python may be necessary.
Option 1: Use pyscopg2-binary
Note: This package comes with its own version of some core libraries that may, under certain conditions, cause conflicts with other libraries. See the developer’s notes for more info.
Option 2: Manual Copy from System Install
Some IDEs, at least PyCharm in my experience, may have trouble installing psycopg2
. In such cases, a possible workaround is to install psycopg2 to the main system install of python, then copy those files manually into your project’s virtual environment’s site-packages directory. On a Windows machine, the steps are as follows:
- Using the Windows terminal: pip install psycopg2
- Copy
Program Files/PythonXX/site-packages/psycopg2
to your virtual environments’ site-packages directory.
If installed without elevated privileges, the psycopg2
library may install to the local User’s Python installation. If this is the case (you won’t find the psycopg2 package in the directory above) look in the following directory:
. └── C:/ └── Users/ └── pc/ └── AppData/ └── Roaming/ └── Python/ └── Python38/ └── site-packages/ └── psycopg2
Migrate Changes
Assuming psycopg2 was configured correctly, your project should be adequately configured for basic Postgres usage now. Assuming your project doesn’t require any changes to models or other areas to work with Postgres, running the makemigrations and migrate commands should give you the confirmation of success you need. Below is what the output should look like—for a blank Django project having just configured Postgres:
(venv) C:\path\to\your-project>python manage.py makemigrations No changes detected (venv) C:\path\to\your-project>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying sessions.0001_initial... OK
These are all the core Django models being migrated to the Postgres database.
Discussion
Django is an incredible framework for building multi-purpose web applications ranging from hobbyist projects to enterprise-caliber endeavors. As we’ve seen here, Django can be configured to work with PostgreSQL relatively easily. There may be some quirks depending on your OS or IDE but I’ve still to see anything that would prevent the setup outlined here from being troubleshot.