创建数据库后如何执行docker-entrypoint-initdb.d/init.sql文件? [英] How to execute docker-entrypoint-initdb.d/init.sql files AFTER database is created?
问题描述
我有一个带有Docker的Django应用
I have a Django app with Docker
我想在运行docker-compose up时基于init.sql文件初始化数据库
I want to initialize my database based on init.sql file when running docker-compose up
正确构建了2个容器,并且db_container中提供了init.sql文件
2 containers are correctly built and init.sql file is available in db_container
但是 docker日志db_container
显示错误,指示数据库尚未迁移:
but docker logs db_container
show an error indicating that database has not been migrated yet:
错误:关系table1不存在
ERROR: relation table1 does not exist
执行entrypoint.sh文件时创建数据库(命令python manage.py migration)
Database is created when entrypoint.sh files is executed (command python manage.py migrate)
我不明白何时执行init.db?
I do not understand when init.db is executed?
Dockerfile
FROM python:3.8.3-alpine
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev
RUN apk --update add libxml2-dev libxslt-dev libffi-dev gcc musl-dev libgcc openssl-dev curl
RUN apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev
RUN pip3 install psycopg2 psycopg2-binary
COPY requirements/ requirements/
RUN pip install --upgrade pip && pip install -r requirements/dev.txt
COPY ./entrypoint.sh .
COPY . .
# Run entrypoint.sh
ENTRYPOINT [ "/usr/src/app/entrypoint.sh" ]
entrypoint.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
# nc = netcap -z = scanning
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py flush --no-input
python manage.py migrate
exec "$@"
docker-compose.yml
version: '3.7'
services:
web:
...
depends_on:
- db
db:
image: postgres:12.0-alpine
restart: always
volumes:
- postgres_data:/var/lib/postgres/data/
- ./imports/init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=user
- POSTGRES_DB=db_dev
volumes:
postgres_data:
init.sql
\c db_dev
INSERT INTO table1 (field1,field2,field3) VALUES ('value1','value2','value3');
...
推荐答案
/docker-entrypoint-initdb.d/init.sql
在数据库容器开始运行时执行,而> entrypoint.sh
将在您的Web容器开始运行时执行.由于您的Web容器取决于数据库容器,因此SQL脚本将始终在入口点之前执行.
/docker-entrypoint-initdb.d/init.sql
is executed the moment your database container starts running, while your entrypoint.sh
is executed the moment your web container starts running. Since your web container depends on your database container, the SQL script will always be executed ahead of your entrypoint.
换句话说,您想要的是不可能的.
In other words, what you want is impossible.
您需要在 init.sql
中创建数据库和table1,并告诉Django不要尝试创建它们(如果它们已经存在),或者以某种方式将您的 INSERT ..
添加到要运行的迁移列表.
You need to either create the database and table1 in init.sql
and tell Django not to attempt creating them if they already exists or somehow add your INSERT..
to the list of migrations to be run.
我从没使用过Django,所以我不知道以上两种方法是否可行.
I've never used Django, so I do not know if either of the above is possible.
这篇关于创建数据库后如何执行docker-entrypoint-initdb.d/init.sql文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!