我可以在 pg-promise 中设置连接的search_path(或默认模式)吗?



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

我尝试过什么

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

我也尝试过这样的事情:

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

。但这似乎也不会影响后续查询。

我还发现了这个没有被接受答案的相关问题,并且在评论中似乎建议将其设置为用户级别,我无权这样做,或者上述问题似乎对我不起作用。

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

换句话说:我还可以尝试什么吗,或者我上面提到的解决方案之一毕竟应该起作用,如果是,如何?

我还发现了这个没有被接受的答案的相关问题,并且似乎在评论中提出了上述建议,这似乎对我不起作用。

为什么没有呢?这是正确的解决方案,在用户级别设置架构搜索路径。你应该坚持这个方向。

pg-promise 确实允许您在运行时在事件连接中设置架构,但您最终会在每个新连接上执行一个额外的查询:

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 允许的黑客攻击,而不是使用该库的常见做法,因为它直接对驱动程序执行查询,并且没有任何错误处理,因为处理错误不会对任务或事务产生任何影响。因此,您必须小心避免在此处执行任何可能发出错误的查询。

更新-1

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

const initOptions = {
schema: 'my_schema' // can also be an array of strings
};
const pgp = require('pg-promise')(initOptions);

更新-2

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

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);

更新-3

版本 8.4.0 将参数isFresh替换为事件连接的useCount,因此动态模式最简单的方法是仅使用选项schema

最新更新