创建数据库后如何执行docker-entrypoint-initdb.d/init.sql文件? [英] How to execute docker-entrypoint-initdb.d/init.sql files AFTER database is created?

查看:273
本文介绍了创建数据库后如何执行docker-entrypoint-initdb.d/init.sql文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆