Skip to content

Commit 607b4d1

Browse files
committed
feat: setup database
1 parent bb9f0a8 commit 607b4d1

File tree

13 files changed

+80
-3
lines changed

13 files changed

+80
-3
lines changed

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ EXPOSE 8000
2020
ARG DEV=false
2121
RUN python -m venv /py && \
2222
/py/bin/pip install --upgrade pip && \
23+
apk add --update --no-cache postgresql-client && \
24+
apk add --update --no-cache --virtual .tmp-build-deps \
25+
build-base postgresql-dev musl-dev && \
2326
/py/bin/pip install -r /tmp/requirements.txt && \
2427
if [ $DEV = "true" ]; \
2528
then /py/bin/pip install -r /tmp/requirements.dev.txt ; \
2629
fi && \
2730
rm -rf /tmp && \
31+
apk del .tmp-build-deps && \
2832
adduser \
2933
--disabled-password \
3034
--no-create-home \

app/app/settings.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
For the full list of settings and their values, see
1010
https://docs.djangoproject.com/en/3.2/ref/settings/
1111
"""
12-
12+
import os
1313
from pathlib import Path
1414

1515
# Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -37,6 +37,7 @@
3737
'django.contrib.sessions',
3838
'django.contrib.messages',
3939
'django.contrib.staticfiles',
40+
'core',
4041
]
4142

4243
MIDDLEWARE = [
@@ -75,8 +76,11 @@
7576

7677
DATABASES = {
7778
'default': {
78-
'ENGINE': 'django.db.backends.sqlite3',
79-
'NAME': BASE_DIR / 'db.sqlite3',
79+
'ENGINE': 'django.db.backends.postgresql',
80+
'HOST': os.environ.get('DB_HOST'),
81+
'NAME': os.environ.get('DB_NAME'),
82+
'USER': os.environ.get('DB_USER'),
83+
'PASSWORD': os.environ.get('DB_PASS'),
8084
}
8185
}
8286

app/core/__init__.py

Whitespace-only changes.

app/core/admin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.contrib import admin # noqa
2+
3+
# Register your models here.

app/core/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class CoreConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'core'

app/core/management/__init__.py

Whitespace-only changes.

app/core/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Django command to wait for the database to be available
2+
from django.core.management.base import BaseCommand
3+
import time
4+
from psycopg2 import OperationalError as Psycopg2Error
5+
from django.db.utils import OperationalError
6+
7+
8+
class Command(BaseCommand):
9+
10+
def handle(self, *args, **options):
11+
self.stdout.write("Waiting for database...")
12+
db_up = False
13+
while db_up is False:
14+
try:
15+
self.check(databases=['default'])
16+
db_up = True
17+
except (Psycopg2Error, OperationalError):
18+
self.stdout.write(
19+
self.style.ERROR(
20+
'Database unavailable, waiting for 1 second...'))
21+
time.sleep(1)
22+
23+
self.stdout.write(self.style.SUCCESS('Database available!'))

app/core/migrations/__init__.py

Whitespace-only changes.

app/core/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.db import models # noqa
2+
3+
# Create your models here.

app/core/tests/__init__.py

Whitespace-only changes.

app/core/tests/test_comands.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Test custom Django management commands
2+
3+
from unittest.mock import patch
4+
5+
from psycopg2 import OperationalError as Psycopg2OpError
6+
7+
from django.core.management import call_command
8+
from django.db.utils import OperationalError
9+
from django.test import SimpleTestCase
10+
11+
12+
@patch('core.management.commands.wait_for_db.Command.check')
13+
class CommandTests(SimpleTestCase):
14+
"""Test commands."""
15+
16+
def test_wait_for_db_ready(self, patched_check):
17+
"""Test waiting for database if database ready."""
18+
patched_check.return_value = True
19+
20+
call_command('wait_for_db')
21+
22+
patched_check.assert_called_once_with(databases=['default'])
23+
24+
@patch('time.sleep')
25+
def test_wait_for_db_delay(self, patched_sleep, patched_check):
26+
"""Test waiting for database when getting OperationalError."""
27+
patched_check.side_effect = [Psycopg2OpError] * 2 + \
28+
[OperationalError] * 3 + [True]
29+
30+
call_command('wait_for_db')
31+
32+
self.assertEqual(patched_check.call_count, 6)
33+
patched_check.assert_called_with(databases=['default'])

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
Django>=3.2.4,<3.3
22
djangorestframework>=3.12.4,<3.13
3+
psycopg2>=2.8.6,<2.9

0 commit comments

Comments
 (0)