我可以为 pg-promise 中的连接设置 search_path (或默认架构)吗?

Can I set the search_path (or default schema) for a connection in pg-promise?

如果我可以设置默认模式以用于使用 pg-promise 的连接,那就太好了。

我试过的

我看到在某些语言中可以将 ?searchpath=<schema> 添加到连接字符串以将 <schema> 设置为后续查询的默认架构,但这在 pg- 中不起作用承诺。

我也试过这样的方法:

const database = pgp(connectionString); // connectionString defined earlier, obviously
database.none('SET search_path TO ${schema}`, { schema: '<schema>' });

...但这似乎也不会影响以下查询。

我还发现 没有被接受的答案,在评论中似乎建议在用户级别设置它,我无权这样做,或者上面,这似乎对我不起作用。

而且我发现 this question 最终有一个不同的问题作为根本原因。

换句话说:还有什么我可以尝试的吗?或者我上面提到的解决方案之一到底应该有效吗?如果有效,如何?

I also found which doesn't have an accepted answer and seems to suggest the above in the comments, which doesn't seem to work for me.

为什么没有呢?这是正确的解决方案,setting the schema search path at the user level。你应该朝着那个方向坚持下去。

pg-promise does let you set the schema at run-time, within event connect,但您最终会在每个新连接上执行额外的查询:

const schema = 'my_schema';

const initOptions = {
    connect: (client, dc, isFresh) => {
        if(isFresh) {
            client.query(`SET search_path TO ${schema}`);
        }
    }
};

const pgp = require('pg-promise')(initOptions);

上面的代码示例有点像 pg-promise 允许的 hack,而不是使用库的常见做法,因为它直接对驱动程序执行查询,没有任何错误处理,因为处理错误不会对任务或交易产生任何影响。所以你必须小心避免在这里执行任何可能会出错的查询。

UPDATE-1

Version 8.3.0 的库自动开始支持此功能:

const initOptions = {
    schema: 'my_schema' // can also be an array of strings
};

const pgp = require('pg-promise')(initOptions);

UPDATE-2

版本 8.3.2 也开始支持采用数据库上下文的回调函数(参见 Database 构造函数),因此它可以 return 根据上下文的模式,使其成为在一个模块中使用不同的数据库时可以正确设置模式。

const initOptions = {
    schema: dc => {
        if(dc === /* whatever database context was used */) {
            return 'my_schema';
        }
        // other provisions, if multiple databases are used.

        // or can return nothing, if no schema change is needed.
    }
};

const pgp = require('pg-promise')(initOptions);

UPDATE-3

Version 8.4.0 replaced parameter isFresh with useCount for event connect,因此动态模式最简单的方法是只使用选项 schema