如果我可以使用 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
。