在 Docker Compose 中初始化 Postgres 数据库

For*_*rin 8 postgresql docker docker-compose

我有以下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
Run Code Online (Sandbox Code Playgroud)

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

CREATE TABLE anime ( 
  anime_id INT PRIMARY KEY,
  title TEXT
);
Run Code Online (Sandbox Code Playgroud)

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

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

 - ./preload.sql:/preload/preload.sql
Run Code Online (Sandbox Code Playgroud)

使用该脚本:

copy anime FROM 'docker/data/AnimeList.csv' DELIMITER ',' CSV HEADER;
Run Code Online (Sandbox Code Playgroud)

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

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

Did not find any relation named "anime".
Run Code Online (Sandbox Code Playgroud)

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

For*_*rin 19

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

项目结构

data/
  datasource.csv
db/
  scripts/
    1_init.sql
    2_copy.sql
  Dockerfile
docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

文件

  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
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)
  4. 1_init.sql 身体:

    CREATE TABLE table_name
    (
       --statement body
    );
    
    Run Code Online (Sandbox Code Playgroud)
  5. 并且2_copy.sql

    COPY table_name FROM '/data/datasource.csv' DELIMITER ',' CSV HEADER;
    
    Run Code Online (Sandbox Code Playgroud)

解释

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

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

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

  • 这是一个很棒的答案,应该得到更多的支持。解决了我的问题! (3认同)