PostgreSQL Запрос на создание каталога - PullRequest
1 голос
/ 28 января 2020

Файлы записываются в каталог с помощью запроса COPY:

Copy (SELECT * FROM animals) To '/var/lib/postgresql/data/backups/2020-01-01/animals.sql' With CSV DELIMITER ',';

Однако, если каталог 2020-01-01 не существует, мы получаем ошибку

не удалось открыть файл "/var/lib/postgresql/data/backups/2020-01-01/animals.sql" для записи: нет такого файла или каталога

Postge SQL server выполняется внутри контейнера Docker с сопоставлением томов /mnt/backups:/var/lib/postgresql/data/backups

Запрос Copy отправляется из приложения Node.js вне контейнера Docker.

сопоставленный каталог хоста /mnt/backups был создан Docker Compose и принадлежит root, поэтому приложение Node.js, отправляющее запрос COPY, не может создать отсутствующие каталоги из-за недостаточных разрешений.

Файл резервной копии предназначен для передачи из контейнера Docker на хост Docker.

Вопрос : можно ли использовать запрос SQL для запроса PostgreSQL 11.2 создать каталог, если он не существует? Если нет, как вы будете рекомендовать создание каталога?

Использование Node.js 12.14.1 на хосте Ubuntu 18.04. Использование PostgreSQL 11.2 внутри контейнера, Docker 19.03.5

Ответы [ 2 ]

2 голосов
/ 28 января 2020

Простой способ решить эту проблему - создать файл непосредственно на клиентском компьютере. Используя STDOUT из COPY, вы можете разрешить перенаправление вывода запроса на стандартный вывод клиента, который вы можете перехватить и сохранить в файле. Например, используя psql на клиентском компьютере:

$ psql -U your_user -d your_db -c "COPY (SELECT * FROM animals) TO STDOUT WITH CSV DELIMITER ','" > file.csv 

Создание выходного каталога, если он не существует:

$ mkdir -p /mnt/backups/2020-01/ && psql -U your_user -d your_db -c "COPY (SELECT * FROM animals) TO STDOUT WITH CSV DELIMITER ','" > /mnt/backups/2020-01/file.csv

Примечание: : старайтесь не экспортировать файлы на сервер базы данных. Хотя это возможно, я считаю это плохой практикой. При этом вы либо будете записывать файл в системные каталоги postgres, либо дадите пользователю postgres разрешение на запись в другое место, и это то, что вас не устраивает. Экспортируйте данные напрямую клиенту, используя COPY, как я уже упоминал, или следуйте советам @Schwern. Удачи!

1 голос
/ 28 января 2020

Postgres имеет собственные утилиты резервного копирования и восстановления , которые, вероятно, будут лучшим выбором, чем ваши собственные.

При использовании с одним из форматов архивных файлов и в сочетании с pg_restore, pg_dump обеспечивает гибкий механизм архивирования и передачи. pg_dump может использоваться для резервного копирования всей базы данных, затем pg_restore может использоваться для проверки архива и / или выбора того, какие части базы данных должны быть восстановлены. Наиболее гибкими форматами выходного файла являются «пользовательский» формат (-F c) и «каталог» (-Fd). Они позволяют выбирать и переупорядочивать все заархивированные элементы, поддерживают параллельное восстановление и по умолчанию сжимаются. Формат «каталог» является единственным форматом, который поддерживает параллельные дампы.

Простой сценарий ротации резервной копии может выглядеть следующим образом:

#!/bin/sh

table='animals'
url='postgres://username@host:port/database_name'
date=`date -Idate`
file="/path/to/your/backups/$date/$table.sql"

mkdir -p `dirname $file`

pg_dump $url -w -Fc --table=$table -f $file

Чтобы избежать жесткого кодирования пароля базы данных, -w означает, что он не запрашивает пароль и вместо этого ищет файл пароля . Или вы можете использовать любой из много Postgres вариантов аутентификации .

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