如何在不同的模式上运行相同的功能

时间:2015-08-16 17:51:38

标签: postgresql plpgsql

我有多个架构/用户具有相同的结构但数据不同。在这些数据上执行了一些存储的函数,到目前为止,它们存储在每个模式中。我想将这些函数存储在一个新的模式中,这样可以更容易地更新代码,......因为它会集中化。

我认为,因为search_path被定义为"$user",public,它将引用当前会话/连接的用户,因此来自不同模式的查询最终将具有相同的search_path。 / p>

假设我有一个用户T1的表u1, u2, u3和一个使用此表F1的函数。

最初,F1将被复制到模式u1, u2, u3中,而运行select * from F1()将适用于每个用户。但是,随着用户数量的增加,更新函数会变得越来越困难,因此我希望新的模式functions内部只有一个F1函数。

现在,运行select * from functions.F1()会返回错误,找不到T1。但是用户search_path包含的信息仍然相同。那么为什么search_path会根据执行它的函数而改变,以及如何防止它发生呢?

有关于postgres邮件列表的邮件:http://postgresql.nabble.com/function-doesn-t-see-change-in-search-path-td4971325.html,最后的解决方法是我原来的情况。也许同时发生了变化?

3 个答案:

答案 0 :(得分:1)

实际上,我的想法是正确的。但是,当我创建新模式时,通过导出旧函数,pg_dump在每个函数的定义中添加了SECURITY DEFINER

将此更改为SECURITY INVOKER会按预期(由我)提供行为

来自documentation

  

SECURITY INVOKER表示该函数将使用调用它的用户的权限执行。这是默认值。 SECURITY DEFINER指定该函数将使用创建它的用户的权限执行。

答案 1 :(得分:0)

Add a table parameter to F1.然后将uf1uf2uf3添加到u1u2u3。这些函数只需调用F1并传入正确的表格。

答案 2 :(得分:0)

看看plproxy。这是Skype用于通过具有包装函数的代理数据库在多个数据库分片上运行查询的原因。

您还可以编写一个包装函数,该函数可以查找每个模式中的所有函数并调用它们。