Files
pg-stand-sync/README.md
T
mikhail b30406bbf6 Два режима работы и выбор базы из списка
Интерактивное меню (Dump+Restore / Dump / Restore) и CLI-команды
sync/dump/restore/list/dumps. База и файл дампа выбираются из списка
с фильтрацией по вводу, имя базы больше не зашито в конфиг.

Пароль берётся из конфига, переменной окружения или спрашивается с
терминала; без пароля утилиты вызываются с --no-password, иначе psql
подвисает на приглашении.
@
2026-08-20 03:18:04 +03:00

110 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pg-stand-sync
Перенос базы PostgreSQL со стенда на локальный сервер: `pg_dump -Fc` → пересоздание локальной БД → `pg_restore -j`.
Только stdlib Python 3.10+, внешних зависимостей нет. Утилиты берутся из поставки pgAdmin 4.
Работает в двух режимах: интерактивное меню (запуск без аргументов) и команды CLI.
## Быстрый старт
```bash
copy config.example.json config.json
```
Заполнить `source` (стенд) и `target` (локальная PG), затем:
```bash
python pg_stand_sync.py
```
Появится меню:
```
стенд: postgres@postgresql.lan:5432
локально: postgres@localhost:5432
1. Dump + Restore — снять со стенда и залить локально
2. Dump — только снять дамп со стенда
3. Restore — залить локально готовый дамп
0. Выход
```
После выбора пункта показывается список: для Dump — базы стенда, для Restore — файлы из `dumps`.
Ввод в списке работает так:
| Ввод | Что делает |
|---|---|
| текст | фильтрует список по подстроке (регистр не важен) |
| номер | выбирает пункт; в Dump можно `2,5,7` — несколько баз |
| пусто | сбрасывает фильтр |
| `q` | назад в меню |
`config.json` в `.gitignore` — пароли в репозиторий не попадают.
## CLI
```bash
python pg_stand_sync.py list # базы на стенде
python pg_stand_sync.py dumps # локальные дампы
python pg_stand_sync.py dump zpas # только дамп
python pg_stand_sync.py sync zpas --target-db zpas_l # дамп + restore
python pg_stand_sync.py restore dumps/zpas-20260820-031332.dump
```
Имя базы (или файла) можно не указывать — тогда откроется тот же список с фильтрацией.
| Команда / ключ | Что делает |
|---|---|
| `sync [DB…]` | dump со стенда + restore локально |
| `dump [DB…]` | только снять дампы со стенда (можно несколько баз) |
| `restore [FILE]` | залить готовый `.dump` локально, без обращения к стенду |
| `list` / `dumps` | базы стенда / файлы дампов |
| `menu` | интерактивное меню (то же, что запуск без команды) |
| `--target-db NAME` | имя локальной базы (по умолчанию как на стенде) |
| `--no-recreate` | не делать DROP/CREATE DATABASE, накатить поверх (`pg_restore --clean --if-exists`) |
| `-c, --config PATH` | другой конфиг (несколько стендов — несколько json) |
| `--dry-run` | напечатать команды, ничего не выполнять |
## Конфиг
| Поле | Значение по умолчанию | Смысл |
|---|---|---|
| `pg_bin_dir` | из `PATH` | каталог с `pg_dump.exe`, `pg_restore.exe`, `psql.exe` |
| `dump_dir` | `dumps` | куда складывать дампы (относительный путь — от каталога скрипта) |
| `keep_dumps` | `5` | сколько последних дампов хранить, `0` — не чистить |
| `source.maintenance_database` | `postgres` | база, к которой подключаться для чтения списка баз |
| `source.password_env` | — | имя переменной окружения с паролем вместо `password` в файле |
| `target.database` | `null` | имя локальной базы; `null` — как на стенде |
| `target.recreate` | `true` | DROP + CREATE локальной базы перед восстановлением |
| `dump.schemas` / `exclude_*` | `[]` | ограничение состава: схемы, таблицы, данные таблиц |
| `restore.jobs` | `4` | параллельные воркеры `pg_restore` |
| `restore.exit_on_error` | `false` | падать на первой ошибке восстановления |
| `post_restore_sql` | `[]` | список SQL, выполняемых в целевой базе после восстановления |
Пароль ищется в три шага: `password` в конфиге → переменная окружения из `password_env`
запрос с терминала (один раз за запуск, ввод скрыт). В неинтерактивном запуске третьего шага
нет — либо `password_env`, либо `pgpass.conf`. Пароль всегда уходит в дочерний процесс через
`PGPASSWORD`, в командной строке не появляется; если пароля нет вовсе, утилиты вызываются с
`--no-password`, чтобы скрипт не подвисал на приглашении.
```powershell
$env:STAND_PGPASSWORD = '...'
python pg_stand_sync.py sync zpas
```
## Как это работает
```
config.json
├─ pg_dump -Fc ──► dumps/<db>-<timestamp>.dump (стенд, только чтение)
├─ psql: pg_terminate_backend → DROP DATABASE → CREATE DATABASE (локально)
├─ pg_restore --jobs N --no-owner --no-privileges
└─ post_restore_sql: анонимизация, правка настроек, GRANT'ы
```
Обезличивание данных стенда, если оно нужно, делается через `post_restore_sql` — уже в локальной
базе, чтобы стенд оставался нетронутым.