2016-04-30 3 views
0

Используя PostgreSQL 9.2.8, я пытаюсь восстановить только мои данные из одной базы данных в другую, но триггеры, похоже, все еще работают. Я написал сценарий, показанный ниже, чтобы сделать копию.pg_restore не отключает триггеры

В основном у меня есть dts как моя производственная база данных, и у меня есть DigitalTrafficSystem как моя база данных разработки. Структуры таблиц одинаковы, но у разработчика есть очень разные хранимые процедуры.

Когда восстановление выполняется, база данных DigitalTrafficSystem заканчивается кучей дополнительных строк таблицы, которых нет в базе данных dts, поэтому я предполагаю, что они создаются триггерами.

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

pg_restore: [archiver (db)] could not execute query: ERROR: permission denied: "RI_ConstraintTrigger_c_136691" is a system trigger 
Command was: ALTER TABLE usage ENABLE TRIGGER ALL; 

Я предполагаю, что триггеры отключены, но только что триггер уровень системы не может (ошибочно?) отключиться.

Вот мой сценарий:

#!/bin/sh 

PGUSER=dts 
FILE=/tmp/.dts.db.$$ 

# Dump the schema of the DB as we want this to keep 
pg_dump -s DigitalTrafficSystem -f $FILE 

dropdb -U _postgres DigitalTrafficSystem 
if [ $? -ne 0 ]; then 
    exit; 
fi 

createdb -U _postgres -O dts DigitalTrafficSystem 
if [ $? -ne 0 ]; then 
    exit; 
fi 

# Restore the schema 
psql -d DigitalTrafficSystem -f $FILE 

# Dump the data of the real production database 
pg_dump -Fc -a dts -f $FILE > /dev/null 
if [ $? -ne 0 ]; then 
    exit; 
fi 

# Restore only the data from the real database to our development one 
pg_restore -a -d DigitalTrafficSystem --disable-triggers -S dts $FILE 

rm $FILE 
+0

Это определенно триггеры. Я запустил все, кроме последнего pg_restore, открыл базу данных и вручную удалил все триггеры, затем выполнил команду pg_restore, и у меня нет неверных данных. Очевидно, я не могу делать это вручную каждый раз, когда я хочу переписать базу данных. – Gargoyle

+0

Похоже, вы пытаетесь восстановить -data-only в пустую базу данных (только что созданное и не содержащее таблиц). Вам также понадобятся определения таблиц в вашей целевой БД, вы не можете вставлять их в несуществующие столы. – wildplasser

+0

Как-то я пропустил копирование в 'psql -d DigitalTrafficSystem -f $ FILE', который запускается после создания базы данных, которая восстанавливается на основе сбрасываемой схемы. – Gargoyle

ответ

0

Я предполагаю, что (? Ошибочно), что триггеры отключены, но только что триггер уровня система не могла отключенным.

Нет, потому что успех команды SQL является вопросом «все или ничего». Команда, которая не является предположительно формы:

ALTER TABLE usage DISABLE TRIGGER ALL; 

и она должна потерпеть неудачу, она не будет выполнена полностью, а не делать половину работы, которая будет отключить триггер на уровне пользователя и оставляя RI-ограничения триггеры включены.

pg_restore док говорит:

 Presently, the commands emitted for --disable-triggers must be done 
     as superuser. So you should also specify a superuser name with -S 
     or, preferably, run pg_restore as a PostgreSQL superuser. 

и

-S username, --superuser=username 
     Specify the superuser user name to use when disabling triggers. 
     This is relevant only if --disable-triggers is used. 

Но ваш dts не суперпользователя. Похоже, что _postgres - суперпользователь, согласно остальной части сценария. В таком случае, почему бы не передать его -S?

Еще один момент, как примечания @wildplasser в комментариях, немного странно беспокоить триггеры в совершенно новой базе данных, так как ваш скрипт создает базу данных и сразу запускает импорт данных. Можем ли мы предположить, что это база данных template1, которая содержит эти объекты, с этими триггерами? Но тогда обратите внимание, что данные в таблицах от template1 также импортируются во вновь созданную базу данных, поэтому их также необходимо учитывать для любой дополнительной строки, найденной между источником дампа и конечным результатом в базе данных назначения ,

+0

Передача _postgres для аргумента -S не дает разрешения разрешить установку авторизации сеанса. – Gargoyle

+0

@Gargoyle: Я думаю, следуйте советам документа: _preferably, запустите pg_restore как PostgreSQL superuser_ –

+0

ОК, я обнаружил, что если бы я запускал 'psql -U _postgres DigitalTrafficSystem', я мог бы затем« изменять user dts SUPERUSER », и теперь он работает без ошибок. Благодаря! – Gargoyle