Инициализировать Postgres DB в Docker Compose - PullRequest
0 голосов
/ 18 июня 2019

У меня есть следующий 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
);

Затем я хотел бы заполнить базу данных Postgres данными из файла CSV.

Я пыталсядобавьте еще один том в 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".

Мой вопрос: как предварительно загрузить контейнер Postgres с данными CSVфайл в docker-compose?

1 Ответ

0 голосов
/ 26 июня 2019

Мне удалось заставить его работать, используя пользовательский 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
    COPY *.sql /docker-entrypoint-initdb.d/
    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 создает папку Dockerfile из db и делает ее доступной через порт 5431.В качестве свойств окружающей среды используются основные свойства postgres.И в конце data папка с CSV-файлом копируется в контейнер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...