您只需初始化一次数据库连接。如果要在模块之间共享,则将其放入自己的模块文件中,如下所示:
const initOptions = {
// initialization options;
};
const pgp = require('pg-promise')(initOptions);
const cn = 'postgres://username:password@host:port/database';
const db = pgp(cn);
module.exports = {
pgp, db
};
请参阅支持的初始化选项。
更新-1
如果您尝试使用相同的连接详细信息创建多个数据库对象,该库将向控制台输出警告:
WARNING: Creating a duplicate database object for the same connection.
at Object.<anonymous> (D:\NodeJS\tests\test2.js:14:6)
这表明您的数据库使用模式很糟糕,即您应该共享数据库对象,如上所示,而不是重新创建它。而且从 6.x 版本开始,它变得至关重要,每个数据库对象都维护自己的连接池,因此复制这些将另外导致连接使用率低下。
此外,没有必要导出pgp
- 初始化的库实例。相反,您可以这样做:
module.exports = db;
如果在某些模块中您需要使用库的根目录,您可以通过属性$config访问它:
const db = require('../db'); // your db module
const pgp = db.$config.pgp; // the library's root after initialization
更新-2
一些开发人员报告(问题 #175)某些框架,如 NextJS 设法以破坏单例模式的方式加载模块,这导致数据库模块加载多次,并产生duplicate database
警告,即使来自 NodeJS观点它应该只是工作。
下面是解决此类集成问题的方法,方法是使用Symbol将单例强制进入全局范围。让我们创建一个可重用的助手来创建单例......
// generic singleton creator:
export function createSingleton<T>(name: string, create: () => T): T {
const s = Symbol.for(name);
let scope = (global as any)[s];
if (!scope) {
scope = {...create()};
(global as any)[s] = scope;
}
return scope;
}
使用上面的帮助程序,您可以将 TypeScript 数据库文件修改为:
import * as pgLib from 'pg-promise';
const pgp = pgLib(/* initialization options */);
interface IDatabaseScope {
db: pgLib.IDatabase<any>;
pgp: pgLib.IMain;
}
export function getDB(): IDatabaseScope {
return createSingleton<IDatabaseScope>('my-app-db-space', () => {
return {
db: pgp('my-connect-string'),
pgp
};
});
}
然后,在使用数据库的任何文件的开头,您可以执行以下操作:
import {getDB} from './db';
const {db, pgp} = getDB();
这将确保持久的单例模式。