首页 > 解决方案 > 在nodejs中使用异步配置续集

问题描述

几天来我一直在摇头,因为我在 Sequelize 中找不到有效的异步配置示例

如您所知,您可以像这样简单地配置一个 Sequelize 实例

const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname')

然后声明你的模型

const User = sequelize.define('User', {
  // Model attributes are defined here
  firstName: {
    type: DataTypes.STRING,
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING
    // allowNull defaults to true
  }
}, {
  // Other model options go here
});

但是,当 db 凭据来自外部服务时会发生什么?

const credentials = await getDbCredentials();
const sequelize = new Sequelize({credentials})


由于 sequelize 模型的创建与实例创建相结合(与许多其他 ORM 不同),这成为一个大问题。

我目前的解决方案如下:


const Sequelize = require("sequelize");

// Models
const { User } = require("./User");

const env = process.env.NODE_ENV || "development";
const db = {};

let sequelize = null;

const initSequelize = async () => {
  if (!sequelize) {
      let configWithCredentials = {};

      if (env === "production") {
        const credentials = await getDbCredentials();
        const { password, username, dbname, engine, host, port } = credentials;
        configWithCredentials = {
          username,
          password,
          database: dbname,
          host,
          port,
          dialect: engine,
          operatorsAliases: 0
        };
      }

      const config = {
        development: {
          // Dev config 
        },
        production: configWithCredentials,
      };

      sequelize = new Sequelize(config[env]);

      sequelize.authenticate().then(() => {
         console.log("db authenticated")
        });
      });
  }

  db.User = User;

  db.sequelize = sequelize;
  db.Sequelize = Sequelize;
};

initSequelize().then(() => {
  console.log("done");
});

module.exports = db;

但是我觉得这不是一个好方法,因为初始化的异步性质,有时db是未定义的。有没有更好的方法来处理这件事?谢谢

标签: javascriptnode.jsamazon-web-servicesasynchronoussequelize.js

解决方案


您可以使用 beforeConnect 钩子实现此目的,如下所示:

sequelize = new Sequelize(config.database, '', '', config);
sequelize.beforeConnect(async (config) => {
    config.username = await getSecretUsername();
    config.password = await getSecretPassword();
});

将初始凭据留空,然后使用 beforeConnect 更改配置。不确定这是否是最干净的使用方式,但似乎可以正常工作。

https://sequelize.org/master/manual/hooks.html


推荐阅读