Недавно столкнулся с проблемой переноса данных в postgresql, как оказалось, сделать дамп и потом загрузку данных в PostgreSQL несколько сложнее, чем в MySQL. Рассмотрим как это сделать с помощью двух команд — pg_dump и pg_restore.
Для начала делаем дамп с сервера, откуда переносим данные:
1 | $ pg_dump -b -O -F c dbname -h localhost -U dbuser -p 5433 > dump |
Это создаст полный дамп базы dbname с BLOB’ами и без owner’а, в специальном формате для pg_restore.
Далее, создаём базу данных на сервере, где будем делать загрузку данных:
1 2 3 4 5 6 7 8 9 | $ sudo su postgres $ psql # CREATE DATABASE dbname OWNER test; $ psql dbname dbname# DROP EXTENSION plpgsql; |
Последняя команда нужна не во всех случаях, просто мой шаблон BD в postgresql уже содержал по дефолту объявление plpgsql и из-за этого загрузка данных вываливалась с ошибкой. Далее сама процедура загрузки:
1 | $ pg_restore -e -O -1 -d dbname dump |
Флаги в данном случае означают следующее:
- Остановиться в случае ошибки.
- Не выполнять восстановление прав (в моём случае на двух разных серверах просто были разные пользователи БД, что также вызывало ошибку импорта).
- Выполнить всё в одной транзакции (если вдруг возникнет ошибка — будет проще начать с нуля).
Далее, поскольку пользователи на двух разных серверах различались и восстановление дампа происходило без восстановления пользователя, необходимо проставить права для пользователя test (выставляются права на таблицы, последовательности и представления aka views). В моём случае команды выполнялись от пользователя pgsql:
1 2 3 4 5 | $ for tbl in `psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" dbname` ; do psql -c "alter table $tbl owner to test" dbname ; done $ for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" dbname` ; do psql -c "alter table $tbl owner to test" dbname ; done $ for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" dbname` ; do psql -c "alter table $tbl owner to test" dbname ; done |
Не забудьте изменить везде dbname на соответствующие имена баз и, конечно, поменять где необходимо имя пользователя и т.п.
P.S. Возможно, последние 3 команды можно заменить внутренними средствами PostgreSQL, но для меня такой вариант приемлем.
Update
Вышеперечисленные команды для переназначения прав можно завернуть в shell-скрипт. Например, в такой:
1 2 3 4 5 6 7 | #!/bin/sh for tbl in `psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" $1` ; do psql -c "alter table $tbl owner to $2" $1 ; done for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" $1` ; do psql -c "alter table $tbl owner to $2" $1 ; done for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" $1` ; do psql -c "alter table $tbl owner to $2" $1 ; done |
Первый параметр скрипта — имя БД, 2й — имя пользователя, на которого необходимо назначить права.