Postgresql pg_还原未禁用触发器
使用PostgreSQL 9.2.8,我试图将数据从一个数据库恢复到另一个数据库,但触发器似乎仍在运行。我已经编写了如下所示的脚本来进行复制 基本上我有Postgresql pg_还原未禁用触发器,postgresql,postgresql-9.2,pg-restore,Postgresql,Postgresql 9.2,Pg Restore,使用PostgreSQL 9.2.8,我试图将数据从一个数据库恢复到另一个数据库,但触发器似乎仍在运行。我已经编写了如下所示的脚本来进行复制 基本上我有dts作为我的生产数据库,我有DigitalTrafficSystem作为我的开发数据库。表结构是相同的,但是dev-one有非常不同的存储过程 当还原运行时,DigitalTrafficSystem数据库最终会得到一堆额外的表行,这些行在dts数据库中不存在,因此我假设它们是由触发器创建的 对于每个表,我得到的与触发器相关的消息如下所示: pg
dts
作为我的生产数据库,我有DigitalTrafficSystem
作为我的开发数据库。表结构是相同的,但是dev-one有非常不同的存储过程
当还原运行时,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;
我(错误地)假设触发器是关闭的,但是系统级触发器不能被禁用
这是我的剧本:
#/垃圾箱/垃圾箱
PGUSER=dts
FILE=/tmp/.dts.db$$
#转储数据库的模式,因为我们希望它保持不变
pg_dump-s DigitalTrafficSystem-f$文件
dropdb-U\U postgres数字交通系统
如果[$?-ne 0];然后
出口
fi
createdb-U\U postgres-O dts数字流量系统
如果[$?-ne 0];然后
出口
fi
#恢复模式
psql-d DigitalTrafficSystem-f$文件
#转储实际生产数据库的数据
pg_dump-Fc-a dts-f$FILE>/dev/null
如果[$?-ne 0];然后
出口
fi
#仅将真实数据库中的数据恢复到我们的开发数据库中
pg_restore-a-d DigitalTrafficSystem--禁用触发器-S dts$文件
rm$文件
我(错误地)假设触发器已关闭,但仅此而已
无法禁用系统级触发器
不,因为SQL命令的成功与否取决于成败。失败的命令可能是以下形式:
ALTER TABLE usage DISABLE TRIGGER ALL;
如果它失败了,它将完全失败,而不是完成一半的工作,这将禁用用户级触发器并保持启用RI约束触发器
pg_restore
doc说:
及
但是您的dts
不是超级用户。根据脚本的其余部分,似乎\u postgres
是一个超级用户。在这种情况下,为什么不将其传递给-S
另一点是,就像注释中的@wildplasser注释一样,在一个全新的数据库中被触发器困扰有点奇怪,因为您的脚本创建了一个数据库,并立即运行一个仅数据导入。我们是否可以假设是template1
数据库包含这些对象和触发器?
但是,请注意,template1
中的表中的数据也会导入到新创建的数据库中,因此在转储源和目标数据库中的最终结果之间找到的任何其他行中,也必须考虑这些数据
我(错误地)假设触发器已关闭,但仅此而已
无法禁用系统级触发器
不,因为SQL命令的成功与否取决于成败。失败的命令可能是以下形式:
ALTER TABLE usage DISABLE TRIGGER ALL;
如果它失败了,它将完全失败,而不是完成一半的工作,这将禁用用户级触发器并保持启用RI约束触发器
pg_restore
doc说:
及
但是您的dts
不是超级用户。根据脚本的其余部分,似乎\u postgres
是一个超级用户。在这种情况下,为什么不将其传递给-S
另一点是,就像注释中的@wildplasser注释一样,在一个全新的数据库中被触发器困扰有点奇怪,因为您的脚本创建了一个数据库,并立即运行一个仅数据导入。我们是否可以假设是template1
数据库包含这些对象和触发器?
但是,请注意,来自
template1
的表中的数据也会导入到新创建的数据库中,因此在转储源和目标数据库中的最终结果之间找到的任何其他行中,也必须考虑这些数据。这肯定是触发器。我运行了最后一次pg_恢复,打开数据库,手动删除所有触发器,然后运行pg_恢复命令,没有出现无效数据。显然,我无法在每次重写数据库时手动执行此操作。看起来您正在尝试将--仅数据还原到空数据库(新创建的,不包含表)中,您的目标数据库中也需要表定义,您无法插入到不存在的表中。不知何故,我错过了在创建数据库后运行的psql-d DigitalTrafficSystem-f$文件中的复制,该文件基于转储的架构进行恢复。这肯定是触发器。我运行了最后一次pg_恢复,打开数据库,手动删除所有触发器,然后运行pg_恢复命令,没有出现无效数据。显然,我无法在每次重写数据库时手动执行此操作。看起来您正在尝试将--仅数据还原到空数据库(新创建的,不包含表)中,您的目标数据库中也需要表定义,您无法插入到不存在的表中。不知何故,我错过了在创建数据库后运行的psql-d DigitalTrafficSystem-f$文件中的复制,它根据转储的架构进行还原。将_postgres传递给-S参数失败,表示设置会话授权的权限被拒绝。@石像鬼:我想按照文档的建议:最好以PostgreSQL超级用户的身份运行pg_restore OK,我发现,如果我运行了psql-U\U postgres DigitalTrafficSystem
,我就可以alteruser dts SUPERUSER
,现在它运行起来没有错误。谢谢将_postgres传递给-S参数失败,表示设置会话授权的权限被拒绝。@Gargoyle:我想按照文档的建议:最好运行pg_restore a
-S username, --superuser=username
Specify the superuser user name to use when disabling triggers.
This is relevant only if --disable-triggers is used.