我知道你为什么在这里。您已经达到了希望使用续集库与多个数据库进行交互的地步。但是,您最近注意到续集文档提到
如果您是从一个过程中连接到数据库的,则应仅创建一个续集实例。续集将在初始化时设置一个连接池。
因此,这意味着我们必须为每个数据库生成一个新实例,我们打算建立连接。您的目标是规避创建大量实例的需求,这使您寻求帮助。此外,您对写有关这个关键主题的工程师的短缺感到好奇。我也分享你的奇迹。
好消息正在等待您!您来到了理想的位置。下面,我提供了有关如何连接多个数据库而无需创建多个实例的全面,分步的指南。
我想从头开始,但是一位前同事已经在Getting Started with Sequelize and Postgres.上做得很好。如果您尚未创建node.js并续集项目,我建议您单击链接以获取详细说明。但是,如果您已经在研究一个,请随时无视链接。
让我们假设您已经使用了一个名为Customer的Postgres数据库,并且您想添加这4个Postgres(由sequelize支持的任何数据库)数据库到您的Nodejs应用程序:
- 钱包
- auth
- 商人
步骤1:
创建一个.env
文件并填充它,如下所示:
PORT=
API_VERSION=
DB_USERNAME=
DB_PASSWORD=
DB_NAME=
DB_HOST=
DB_PORT=
DB_CUSTOMER_URL=
DB_CUSTOMER_USERNAME=
DB_CUSTOMER_PASSWORD=
DB_CUSTOMER_NAME=
DB_CUSTOMER_HOST=
DB_WALLET_URL=
DB_WALLET_USERNAME=
DB_WALLET_PASSWORD=
DB_WALLET_NAME=
DB_WALLET_HOST=
DB_ROLE_URL=
DB_ROLE_USERNAME=
DB_ROLE_PASSWORD=
DB_ROLE_NAME=
DB_ROLE_HOST=
DB_MERCHANT_URL=
DB_MERCHANT_USERNAME=
DB_MERCHANT_PASSWORD=
DB_MERCHANT_NAME=
DB_MERCHANT_HOST=
DB_AUTH_URL=
DB_AUTH_USERNAME=
DB_AUTH_PASSWORD=
DB_AUTH_NAME=
DB_AUTH_HOST=
第2步:
在配置目录中,修改您的config.ts
(如果不使用Typescript,则config.js
):
import config from "./index";
const { secrets, dbVariables } = config();
module.exports = {
development: {
username: secrets.username,
password: secrets.password,
database: secrets.name,
host: secrets.host,
port: secrets.port,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
databases: {
Customer: {
username: dbVariables.dbCustomerUsername,
password: dbVariables.dbCustomerPassword,
database: dbVariables.dbCustomerName,
host: dbVariables.dbCustomerHost,
port: 5432,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
},
Auth: {
username: dbVariables.dbAuthUsername,
password: dbVariables.dbAuthPassword,
database: dbVariables.dbAuthName,
host: dbVariables.dbAuthHost,
port: 5432,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
},
Wallet: {
username: dbVariables.dbWalletUsername,
password: dbVariables.dbWalletPassword,
database: dbVariables.dbWalletName,
host: dbVariables.dbWalletHost,
port: 5432,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
},
Merchant: {
username: dbVariables.dbMerchantUsername,
password: dbVariables.dbMerchantPassword,
database: dbVariables.dbMerchantName,
host: dbVariables.dbMerchantHost,
port: 5432,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
},
Role: {
username: dbVariables.dbRoleUsername,
password: dbVariables.dbRolePassword,
database: dbVariables.dbRoleName,
host: dbVariables.dbRoleHost,
port: 5432,
dialect: "postgres",
dialectOptions: {
bigNumberStrings: true,
},
},
},
},
};
在这里,我们成功地宣布了另外4个数据库,并具有其证书。现在,您必须注意到我在此文件的开头导入了一个索引文件。这不是强制性的。我总是喜欢为我的秘密键提供一个单独的文件。只要坚持下去,我们将尽快创建该索引文件。现在说到保持代码清洁,让我们创建一个辅助文件,该文件将通过循环循环来读取和声明我们所有的DB环境变量。
步骤3:
在您的帮助者目录中,创建一个dbConfig.ts
文件并输入以下代码行:
export const fetchAllDbConfig = () => {
const DBs = {
CUSTOMER: "Customer",
WALLET: "Wallet",
ROLE: "Role",
MERCHANT: "Merchant",
AUTH: "Auth",
};
const dbVariables = {};
for (let [key, value] of Object.entries(DBs)) {
dbVariables[`db${value}URL`] = process.env[`DB_${key}_URL`] || "";
dbVariables[`db${value}Name`] = process.env[`DB_${key}_NAME`] || "";
dbVariables[`db${value}Host`] = process.env[`DB_${key}_HOST`] || "";
dbVariables[`db${value}Password`] = process.env[`DB_${key}_PASSWORD`] || "";
dbVariables[`db${value}Username`] = process.env[`DB_${key}_USERNAME`] || "";
}
return dbVariables;
};
步骤4:
现在让我们看一下我们之前导入的此索引文件。
回到创建我们在config.ts
文件中导入的索引文件。在同一config Directory中创建一个index.ts
文件并向其添加以下行。
import dotenv from "dotenv";
import path from "path";
import { fetchAllDbConfig } from "../helpers/dbConfig";
// describes a secrets object
type Secrets = Readonly<{
env: string;
version: string;
port: string;
secrets: {
name: string;
host: string;
port: number;
username: string;
password: string;
};
dbVariables: {
dbCustomerURL: string;
dbCustomerName: string;
dbCustomerHost: string;
dbCustomerPassword: string;
dbCustomerUsername: string;
dbWalletURL: string;
dbWalletName: string;
dbWalletHost: string;
dbWalletPassword: string;
dbWalletUsername: string;
dbRoleURL: string;
dbRoleName: string;
dbRoleHost: string;
dbRolePassword: string;
dbRoleUsername: string;
dbAuthURL: string;
dbAuthName: string;
dbAuthHost: string;
dbAuthPassword: string;
dbAuthUsername: string;
dbMerchantURL: string;
dbMerchantName: string;
dbMerchantHost: string;
dbMerchantPassword: string;
dbMerchantUsername: string;
};
}>;
const env = process.env.NODE_ENV || "development";
let envfile: string;
switch (env) {
case "production":
envfile = ".env";
break;
case "test":
envfile = ".env.test";
break;
case "development":
default:
envfile = ".env.local";
break;
}
const envpath: string = path.join(__dirname, "../..", envfile);
let cache: Secrets | any;
export default function config() {
if (!cache) {
dotenv.config({ path: envpath });
cache = Object.freeze({
env,
version: process.env.API_VERSION || "v1",
port: process.env.PORT || "3300",
secrets: {
name: process.env.DB_NAME || "",
host: process.env.DB_HOST || "",
port: +(process.env.DB_PORT || "") || 25,
username: process.env.DB_USERNAME || "",
password: process.env.DB_PASSWORD || "",
},
dbVariables: fetchAllDbConfig(),
});
}
return cache;
}
在这里,我们以更干净的格式声明了我们的变量。另外,请注意我们如何从之前创建的助手/DBConfig导入fetchAllDbConfig
。
步骤5:
仔细编辑models/index.js
文件如下:
"use strict";
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || "development";
const config = require(path.resolve("build/config", "config.js"))[env];
const db = {};
const databases = Object.keys(config.databases);
for (let i = 0; i < databases.length; ++i) {
let database = databases[i];
let dbPath = config.databases[database];
if (config.use_env_variable) {
db[database] = new Sequelize(process.env[config.use_env_variable], config);
} else {
db[database] = new Sequelize(
dbPath.database,
dbPath.username,
dbPath.password,
dbPath
);
}
}
for (let i = 0; i < databases.length; ++i) {
let database = databases[i].toLowerCase();
fs.readdirSync(`${__dirname}/${database}`)
.filter((file) => {
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach((file) => {
const model = require(path.join(`${__dirname}/${database}`, file))(
db[databases[i]],
Sequelize.DataTypes
);
db[model.name] = model;
});
}
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
module.exports = db;
“ db”对象当前保留了我们config.js文件中所有数据库的连接信息。但是,它缺乏有关数据库中模型的详细信息,从而导致SQL查询不正确。为了纠正这一点,我们必须从模型文件中读取模型信息并将其集成到“ db”对象中。
请在我们进行时要注意。为了实现这一目标,我们必须修改如下所示的文件夹结构:
步骤6:
重组您的文件夹树以如下所示。
步骤7:
为每个数据库创建类似于我们的.SequeLizerc文件的新续集选项文件。因此,让我们在包装的目录中创建这两个文件。JSON文件:
- .Seperize-Customer
- 。
- 。
- 。
- 。
在每个文件中,我们可以定义我们的配置,型号,迁移和播种机的目录。对于所有5个文件,请记住更改名称。以下是.sequelize-customer
文件的外观。
const path = require("path");
module.exports = {
config: path.resolve("build/config", "config.js"),
"models-path": path.resolve("src/db/models"),
"seeders-path": path.resolve("src/db/models/customer/seeders"),
"migrations-path": path.resolve("src/db/models/customer/migrations"),
};
步骤8:
在您的软件包中。
{
"customer:migrate": "sequelize --options-path ./.sequelize-customer --env development db:migrate",
"customer:seed": "sequelize --options-path ./.sequelize-customer --env development db:seed:all",
"wallet:migrate": "sequelize --options-path ./.sequelize-wallet --env development db:migrate",
"wallet:seed": "sequelize --options-path ./.sequelize-wallet --env development db:seed:all",
"merchant:migrate": "sequelize --options-path ./.sequelize-merchant --env development db:migrate",
"merchant:seed": "sequelize --options-path ./.sequelize-merchant --env development db:seed:all",
"role:migrate": "sequelize --options-path ./.sequelize-role --env development db:migrate",
"role:seed": "sequelize --options-path ./.sequelize-role --env development db:seed:all",
"auth:migrate": "sequelize --options-path ./.sequelize-auth --env development db:migrate",
"auth:seed": "sequelize --options-path ./.sequelize-auth --env development db:seed:all",
}
从GitHub回购下载
您可以从github repo
克隆此模板步骤9:
恭喜。你做到了。您现在可以从一个实例访问所有五个不同的数据库。
请不要忘记留下类似的评论。