首页 > 解决方案 > 在 Docker Compose 中初始化 Postgres 数据库

问题描述

我有以下docker-compose.yml文件:

version: '3'

services:
  postgres:
    image: postgres
    container_name: postgres
    ports:
      - "5431:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=anime
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

此配置启动 Postgres 数据库。在卷中我定义了 init.sql,它应该建立一个表:

CREATE TABLE anime ( 
  anime_id INT PRIMARY KEY,
  title TEXT
);

然后,我想用 CSV 文件中的数据填充 Postgres 数据库。

我尝试向 docker-compose 添加另一个卷:

 - ./preload.sql:/preload/preload.sql

使用该脚本:

copy anime FROM 'docker/data/AnimeList.csv' DELIMITER ',' CSV HEADER;

CSV 文件位于data文件夹中,与docker-compose.yml.

但它不起作用。数据库已正确创建,但没有表和数据。当我连接到 Docker 容器,运行'psql命令并尝试获取anime表时,我收到以下错误:

Did not find any relation named "anime".

我的问题是:如何在 docker-compose 中使用 CSV 数据文件预加载 Postgres 容器?

标签: postgresqldockerdocker-compose

解决方案


我设法使用 custom 使其工作Dockerfile,这是我的解决方案:

项目结构

data/
  datasource.csv
db/
  scripts/
    1_init.sql
    2_copy.sql
  Dockerfile
docker-compose.yml

文件

  1. CSV文件位于data项目内的文件夹中。

  2. 在项目文件夹中有以下docker-compose.yml文件:

    version: '3.3'
    
    services:
      db:
        build: ./db
        container_name: postgres
        ports:
          - "5431:6666"
        environment:
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
          - POSTGRES_DB=db_name
        volumes:
          - ./data:/data
    
  3. Dockerfile包含:

    FROM postgres:alpine
    ADD scripts/1_init.sql /docker-entrypoint-initdb.d
    ADD scripts/2_copy.sql /docker-entrypoint-initdb.d
    RUN chmod a+r /docker-entrypoint-initdb.d/*
    EXPOSE 6666
    
  4. 1_init.sql身体:

    CREATE TABLE table_name
    (
       --statement body
    );
    
  5. 并且2_copy.sql

    COPY table_name FROM '/data/datasource.csv' DELIMITER ',' CSV HEADER;
    

解释

1_init.sql创建数据库表,它必须具有与 CSV 文件中相同的列名2_copy.sql负责将数据从 CSV 复制到 postgres。

Dockerfile使用 postgres 图像并将所有*.sql文件复制到/docker-entrypoint-initdb.d/. 后来,所有文件都按字母数字顺序执行,这就是*.sql文件以数字开头的原因。最后,端口6666被暴露。

docker-compose.yml构建Dockerfilefromdb文件夹并使其可通过5431端口访问。使用基本的 postgres 属性作为环境属性。最后,data带有 CSV 文件的文件夹被复制到容器中。


推荐阅读