在 NodeJS 中序列化模型加载
Posted
技术标签:
【中文标题】在 NodeJS 中序列化模型加载【英文标题】:Sequelize model loading in NodeJS 【发布时间】:2018-09-03 22:08:35 【问题描述】:我目前正在 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;
我正在寻求对这段代码的通俗解释。这里到底发生了什么?
如果未设置 Node 环境,我确实了解我们默认为 development
的部分,但我需要澄清文件读取部分,即 fs
开始的位置。
【问题讨论】:
哇!非常感谢您的解释。现在清楚多了。还有一件事,这一行是做什么用的: var basename = path.basename(module.filename);? 我相信它只是从路径中删除文件名。如果您愿意,请查看***.com/questions/19811541/… 进行讨论。即我相信返回是index.js
(假设文件名为index.js)。
非常感谢你!您的回复真的很有帮助。
太好了,乐于助人!
【参考方案1】:
首先,请注意,此代码由sequelize-cli
通过运行sequelize init
生成,并放置在models/
文件夹中名为index.js
的文件中。
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);
这对生产时很有帮助。作为示例,我将向您展示我的代码:
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'
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;
);
fs.readdirSync
同步读取其参数中给出的目录。在这种情况下,它是__dirname
,也就是这个 index.js 文件所在的目录。这里,你在models/
目录中定义的模型被拉进来。注意过滤函数只是确保:
然后将每个模型文件键入到带有 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;
最后,一旦我们获得了所有的模型文件(从之前的读取),我们运行每个模型的associate
函数,如果它存在的话。这是在每个模型文件中定义的方法如下:
module.exports = (sequelize, DataTypes) =>
var Model1 = sequelize.define('Model1',
... )
// Class Method
Model1.associate = function (models)
Model1.belongsTo(models.Model2)
return Model1
4.出口使用
您的 sequelize 数据库 (sequelize
) 的实例和 Sequelize
库的实例都被导出。
通过这种方式,我们现在可以执行以下操作:
假设目录结构为
型号/ index.js model1.js model2.jsrequire('./models').Model1 // access to your models
这是您导入和使用模型的方式,而不是直接通过它们的定义文件。这可确保它们正确同步和关联。
同样我们可以访问 sequelize:
require('./models')
.sequelize.sync( force: true ) // access to your sequelize db
【讨论】:
您的config.json
在.gitignore
中吗?
@keshavAggarwal 否 - 签入.config.json
是安全的。如果您不希望公开开发凭据,请使用环境变量。常用的包是dotenv
。 你应该忽略.env
文件。【参考方案2】:
简单来说,这是从与此文件相同的目录中导入所有.js
文件。这是通过sequelize['import']
方法完成的。
此外,假设所有这些文件都包含续集模型,因为导入的返回值映射到名为 db
的字典上。
db[model.name] = model
导入所有文件并将模型映射到db
后,将运行循环以在每个模型上调用associate
,前提是该模型包含关联方法。通常使用 associate 方法来定义模型之间的所有关联,即hasMany
、hasOne
、belongsTo
等。
【讨论】:
太棒了!谢谢。以上是关于在 NodeJS 中序列化模型加载的主要内容,如果未能解决你的问题,请参考以下文章