Connect Django to PostgreSQL in Docker
Tags: django, postgres, docker
Published: 2020-05-23 12:04:28

Django uses SQLite database by default, now we want to switch it to postgreSQL. Firstly, we fetch postgreSQL docker image and start an instance

```
docker pull postgres
docker run --name my-postgres -v /tmp/my-pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=my-password -p 127.0.0.1:5432:5432 -d postgres
```
The docker instance name can be whatever you want, here it's named my-postgres for instance, and we mount a volume (e.g */tmp/my-pgdata*) to our container, so that the database files are easier to access for other tools or applications on our host system. And remember to forward the default postgreSQL port and use `-d` to put it to background. Next, we install postgreSQL command line client if you haven't done that yet.
```
sudo apt-get install postgresql-client
```
Then, we connect to postgreSQL, either command below should work, `postgres` is the default database and user name
```
psql postgresql://postgres:my-password@127.0.0.1:5432/postgres
docker exec -it my-postgres psql postgresql://postgres:my-password@127.0.0.1:5432/postgres
```

If everything goes as expected, we should be able to connect and list the databases

```
~ ❯ docker exec -it my-postgres psql postgresql://postgres:my-password@127.0.0.1:5432/postgres
psql (12.3 (Debian 12.3-1.pgdg100+1))
Type "help" for help.

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)
```


After it's up and running, we install the postgreSQL adapter `psycopg2` to our Django project
```
pip install psycopg2
```

Modify `settings.py` in the project to use Postgres instead

```
. . .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'my-password',
        'HOST': '127.0.0.1',
        'PORT': '5432'
    }
}

. . .
```

Now, we are ready to go
```
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
```
Let's switch to the database, we can see the default tables are created by Django, cheers!

```
postgres=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# \dt
                   List of relations
 Schema |            Name            | Type  |  Owner
--------+----------------------------+-------+----------
 public | account_emailaddress       | table | postgres
 public | account_emailconfirmation  | table | postgres
 public | auth_group                 | table | postgres
 public | auth_group_permissions     | table | postgres
 public | auth_permission            | table | postgres
 public | auth_user                  | table | postgres
 public | auth_user_groups           | table | postgres
 public | auth_user_user_permissions | table | postgres
 public | authtoken_token            | table | postgres
 public | django_admin_log           | table | postgres
 public | django_content_type        | table | postgres
 public | django_migrations          | table | postgres
 public | django_session             | table | postgres
 public | django_site                | table | postgres
(18 rows)
```