在NodeJS中加载Sequelize模型

Kin*_*ejo 2 node.js sequelize.js

我目前在Scotch.io上学习使用NodeJS,Express,PostgreSQL和Sequelize然后我遇到了这个:

'use strict';

var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var basename  = path.basename(module.filename);
var env       = process.env.NODE_ENV || 'development';
var config    = require(__dirname + '/../config/config.json')[env];
var db        = {};

if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
  var sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(function(file) {
    return (file.indexOf('.') !== 0) && (file !== basename) & (file.slice(-3) === '.js');
  })
  .forEach(function(file) {
    var model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(function(modelName) {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

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

module.exports = db;
Run Code Online (Sandbox Code Playgroud)

我需要有人请用简单的语言帮助解释这些.到底发生了什么?

我确实理解我们默认的部分development是Node环境没有设置但是我真的需要澄清文件读取部分,即fs从哪里开始.

非常感谢.

vap*_*aid 8

首先,注意,这个代码是由生成的sequelize-cli运行sequelize init,并放置在一个称为文件index.js位于在models/文件夹中.

1.配置环境

if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
  var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
Run Code Online (Sandbox Code Playgroud)

这在生产中很有用.举个例子,我会告诉你我的代码:

module.exports = {
  development: {
    dialect: 'postgres',
    username: '<username name>',
    password: 'test',
    database: '<db name>',
    host: 'localhost'
  },
  production: {
    dialect: 'postgres',
    dialectOptions: {
      ssl: true
    },
    protocol: 'postgres',
    use_env_variable: 'DATABASE_URL'
  }
}
Run Code Online (Sandbox Code Playgroud)

Heroku设置了一个DATABASE_URL我简单指向的过程变量.用户名,密码等是从这里获得的,而不是config.js像开发凭据那样明确地列出它们.

2.导入/阅读模型

fs
  .readdirSync(__dirname)
  .filter(function(file) {
    return (file.indexOf('.') !== 0) && (file !== basename) & (file.slice(-3) === '.js');
  })
  .forEach(function(file) {
    var model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });
Run Code Online (Sandbox Code Playgroud)

fs.readdirSync同步读取其参数中给出的目录.在这种情况下,它__dirname是这个index.js文件所在的目录.这里,您在models/目录中定义的模型被拉入.请注意,过滤器函数只是确保:

  • 有文件要读
  • 它排除了这个文件(即不是index.js)
  • 他们以'.js'结尾

然后使用该行将每个模型文件键入到导出对象中 db[model.name] = model;

3.关联每个模型

Object.keys(db).forEach(function(modelName) {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

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

module.exports = db;
Run Code Online (Sandbox Code Playgroud)

最后,一旦我们获得了所有模型文件(来自前一个读取),我们就运行每个模型的associate函数(如果存在).这是在每个模型文件中定义的方法,如下所示:

module.exports = (sequelize, DataTypes) => {
  var Model1 = sequelize.define('Model1',
    { ... })

  // Class Method
  Model1.associate = function (models) {
    Model1.belongsTo(models.Model2)
  }
  return Model1
}
Run Code Online (Sandbox Code Playgroud)

4.出口使用

将导出sequelize database(sequelize)的实例和Sequelize库的实例.

通过这种方式,我们现在可以执行以下操作:

假设一个目录结构

  • 楷模/
    • index.js
    • model1.js
    • model2.js

require('./models').Model1 // access to your models

这是您导入和使用模型的方式,而不是直接通过其定义文件.这可确保它们同步并正确关联.

同样我们可以访问sequelize:

require('./models')
  .sequelize.sync({ force: true }) // access to your sequelize db
Run Code Online (Sandbox Code Playgroud)