Совершенно новый для Docker , я пытаюсь добавить выполнение пользовательского sql сценария (триггеры и функции) в процесс миграции Django, и я начинаю чувствовать себя немного потерянным , В целом, то, что я пытаюсь достичь, следует этому милому понятному учебнику . В этом руководстве миграции выполняются путем выполнения сценария точки входа. В Dockerfile:
# run entrypoint.sh
ENTRYPOINT ["/usr/src/my_app/entrypoint.sh"]
Вот entrypoint.sh :
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
# tried several with and without combinations
python manage.py flush --no-input
python manage.py makemigrations my_app
python manage.py migrate
exec "$@"
Пока все хорошо. Обращаясь к вопросу об интеграции выполнения пользовательских сценариев sql в процессе миграции, большинство прочитанных мною статей (например, эта ) рекомендуют создать пустую миграцию, чтобы добавить выполнение SQL заявления. Вот что я имею в
my_app/migrations/0001_initial_data.py
import os
from django.db import migrations, connection
def load_data_from_sql(filename):
file_path = os.path.join(os.path.dirname(__file__), '../sql/', filename)
sql_statement = open(file_path).read()
with connection.cursor() as cursor:
cursor.execute(sql_statement)
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
operations = [
migrations.RunPython(load_data_from_sql('my_app_base.sql'))
]
Как указано зависимости , этот шаг зависит от начального (0001_initial.py
):
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Unpayed',
fields=[
etc etc
[ Проблема ] Однако, даже когда я пытаюсь выполнить миграцию вручную (docker-compose exec web python manage.py makemigrations my_app
), я получаю следующую ошибку, поскольку db в контейнере postgresql пусто
File "/usr/src/my_app/my_app/migrations/0001_initial_data.py", line 21, in Migration
migrations.RunPython(load_data_from_sql('my_app_base.sql'))
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 82, in _execute
....
return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "auth_user" does not exist
[ Что я не понимаю ] Однако, когда я вхожу в контейнер, удаляю 0001_initial_data.py
и запускаю ./entrypoint.sh
, все работает как чудо и создаются таблицы. Позже я могу добавить 0001_initial_data.py
вручную, запустить entrypoint.sh и получить мои функции. То же самое, когда я удаляю этот файл перед запуском docker-compose up -d --build
: создаются таблицы.
Мне кажется, что я упускаю какой-то очевидный способ и проще при попытке интегрировать миграции сценариев sql таким каноническим способом. Все, что мне нужно, это запустить этот скрипт после завершения 0001_initial миграции. Как бы вы это сделали?
[ edit ] docker-compose.yml:
version: '3.7'
services:
web:
build:
context: ./my_app
dockerfile: Dockerfile
command: python /usr/src/my_app/manage.py runserver 0.0.0.0:8000
volumes:
- ./my_app/:/usr/src/my_app/
ports:
- 8000:8000
environment:
- SECRET_KEY='o@@xO=jrd=p0^17svmYpw!22-bnm3zz*%y(7=j+p*t%ei-4pi!'
- SQL_ENGINE=django.db.backends.postgresql
- SQL_DATABASE=postgres
- SQL_USER=postgres
- SQL_PASSWORD=N0tTh3D3favlTpAssw0rd
- SQL_HOST=db
- SQL_PORT=5432
depends_on:
- db
db:
image: postgres:10.5-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
volumes:
postgres_data:
Джанго: 2,2
питон: 3,7