pg-promise:将连接传递到不同库的推荐模式

pg-promise: Recommended pattern for passing connections to different libraries

这个问题是针对 pg-promise 的,它的推荐使用模式 & 基于以下假设,

It does-not make sense to create more than a single pgp instance, if they are connecting to same DB(also enforced by the good warning message of "Creating a duplicate database object for the same connection.")

鉴于: 我有 2 个单独的包需要数据库连接,目前它们从外部在构造函数中获取连接字符串并在其中创建连接对象,这导致重复连接对象的警告并且是公平的,因为它们都与同一个数据库对话并且有可能在这里进行优化(因为我控制着这些包)。

Then:为了防止这种情况,我想到了实现依赖注入,为此我在库构造函数中传递了一个解析函数,它为它们提供了数据库连接对象。

问题:有一些设置在顶层,例如解析器和帮助器以及事务模式,这些设置对于这些包中的每一个都可能不同,对于此类设置的建议是什么或是否有更好的模式来解决这些问题。 例如:

const pg = require('pg-promise');
const instance = pg({"schema": "public"});
instance.pg.types.setTypeParser(1114, str => str);//UTC Date which one library requires other doesnt
const constring = "";
const resolveFunctionPackage1 = ()=>instance(constring);
const resolveFunctionPackage2 = ()=>instance(constring);

总结:为pg-promise实现依赖注入的最佳方式是什么?

I have 2 individual packages which need DB connection, currently they take connection string in constructor from outside and create connection object inside them

这是一个严重的设计缺陷,永远无法正常工作。任何使用数据库的独立包都必须能够重用现有的连接池,这在连接使用方面是最有价值的资源。 Head-on 独立模块内连接池的重复将耗尽现有的物理连接,并阻碍所有其他需要使用相同物理连接的模块的性能。

如果 third-party 库支持 pg-promise,它应该能够接受用于访问数据库的实例化 db 对象。

并且如果 third-party 库仅支持 基本驱动程序 ,它至少应该接受实例化的 Pool 对象。在 pg-promise 中,db 对象通过 db.$pool.

公开底层 Pool 对象

what happens when they want to set conflicting typeparsers?

会有冲突,因为pg.types是底层驱动单例,所以只能用一种方式配置。这是一个不幸的限制。

避免它的唯一方法是让可重用模块从不 re-configure 解析器。它应该只在实际的客户端应用程序中完成。

更新

严格来说,应避免将应用程序的 database-access 层拆分为多个模块,这可能会导致许多问题。

但专门针对类型解析器的分离,该库支持在池级别设置自定义类型解析器。 See example here。请注意,更新仅适用于 TypeScript,即在 JavaScript 客户端中它已经工作了一段时间。

因此您仍然可以让您的单独模块创建自己的 db 对象,但我建议您将其连接池大小限制为最小值,例如 1:

const moduleDb = pgp({
    // ...connection details...

    max: 1, // set pool size to just 1 connection

    types: /* your custom type parsers */
});