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

时间:2018-04-16 10:12:10

标签: javascript 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 related question没有得到接受的答案,并且在评论中似乎建议将其设置为用户级别,我没有权利这样做,或者以上,似乎对我不起作用。

我发现this question最终因为根本原因而遇到了不同的问题。

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

1 个答案:

答案 0 :(得分:1)

  

我还发现this related question没有接受的答案,似乎在评论中提出了上述内容,这似乎对我没用。

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

pg-promise允许您在事件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构造函数),因此它可以根据上下文返回模式,从而可以正确设置模式。在一个模块中使用不同的数据库。

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将参数isFresh替换为事件connectuseCount,因此动态架构最简单的方法就是使用选项schema