如何组织使用sequelize的节点应用程序?
我正在寻找一个使用序列化ORM的示例nodejs应用程序。
我主要担心的是,如果由于require()依赖性循环,这些模型之间存在复杂的关系,那么在单独的js文件中定义模型几乎是不可能的。 也许人们把所有的模型定义在一个非常长的文件中?
我主要感兴趣的是如何定义模型,并通过应用程序使用。 我想有一些validation,我正在做我自己的事情是“好”的方式。
短篇小说
在这种情况下,诀窍不是初始化文件中的模型,而是为了提供初始化的必要信息,并让集中模块负责模型的设置和实例化。
所以步骤是:
- 有几个模型文件与模型的数据,如字段,关系和选项。
- 有一个加载所有这些文件并设置所有模型类和关系的单例模块。
- 在app.js文件中设置你的单例模块。
- 从单例模块获取模型类不要在模型文件中使用
require
,而是从单例模型加载模型。
更长的故事
以下是对相应源代码的解决scheme的更详细的描述:
http://jeydotc.github.io/blog/2012/10/30/EXPRESS-WITH-SEQUELIZE.html
编辑:这是一个非常古老的答案! (读取信息)
这在很多方面都很老很有限!
-
首先 ,正如@jinglesthula在评论中提到的(我也经历过) – 需要这些文件存在问题。 这是因为
require
和readdirSync
不一样。 -
其次 – 关系非常有限 – 代码不会为这些关联提供选项 ,因此无法
through
属性创buildbelongsToMany
。 你可以做最基本的关联。 -
第三 – 你们在模特关系方面非常有限! 如果仔细阅读代码,你会发现关系是一个对象而不是一个数组 ,所以如果你想创build多个相同types的关联(比如拥有两次
belongsTo
) – 你不能! -
第四 – 你不需要那个单身的东西。 nodejs中的每个模块都是单独的,所以这一切都是非常复杂的。
你应该看到农场的答案! (这篇文章的链接被破坏了,但是我会用sequelize的官方示例修复它: https : //github.com/sequelize/express-example/blob/master/models/index.js – 你可以浏览整个项目,以了解发生了什么)。
PS我正在编辑这篇文章,因为它是如此upvoted,人们甚至不会看到任何新的答案(如我所做的)。
编辑:只是改变了链接到同一篇文章的副本,但在Github页面
SequelizeJS在他们的网站上有一篇文章解决了这个问题。
链接已损坏,但您可以在此处find工作示例项目并浏览它。 看到上面编辑的答案,看看为什么这是一个更好的解决scheme
文章摘录:
-
车型/ index.js
这个文件的想法是configuration到数据库的连接并收集所有的模型定义。 一切就绪后,我们将调用每个模型的相关方法。 这个方法可以用来把模型和其他模型联系起来。
var fs = require('fs') , path = require('path') , Sequelize = require('sequelize') , lodash = require('lodash') , sequelize = new Sequelize('sequelize_test', 'root', null) , db = {} fs.readdirSync(__dirname) .filter(function(file) { return (file.indexOf('.') !== 0) && (file !== 'index.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].options.hasOwnProperty('associate')) { db[modelName].options.associate(db) } }) module.exports = lodash.extend({ sequelize: sequelize, Sequelize: Sequelize }, db)
我创build了一个包sequelize-connect来帮助人们处理这个问题。 它遵循Sequelizebuild议的约定: http ://sequelize.readthedocs.org/en/1.7.0/articles/express/
另外它的接口function也更像Mongoose。 它允许您指定模型所在的位置集合,还允许您定义自定义匹配函数以匹配模型文件。
用法基本上是这样的:
var orm = require('sequelize-connect'); orm.discover = ["/my/model/path/1", "/path/to/models/2"]; // 1 to n paths can be specified here orm.connect(db, user, passwd, options); // initialize the sequelize connection and models
然后你可以访问模型并像这样继续:
var orm = require('sequelize-connect'); var sequelize = orm.sequelize; var Sequelize = orm.Sequelize; var models = orm.models; var User = models.User;
希望这可以帮助别人。
我开始在Express.js应用程序中使用Sequelize。 很快遇到了你所描述的性质的问题。 也许我对Sequelize不是很了解,但是对我而言,做一些事情不仅仅是从一张桌子上select并不方便。 而且,通常情况下,您将使用两个或多个表中的select,或纯SQL中的联合,您将不得不运行单独的查询,而Node的asynchronous性质只会增加复杂性。
所以我不再使用Sequelize。 此外,我正在从模型中使用从数据库中提取任何数据的切换。 在我看来,最好是完整地抽取数据。 原因是 – 想象你不只是使用MySQL(在我的情况下,我并排使用MySQL和MongoDB),但是你可以从任何数据提供者和任何传输方法获得你的数据,例如SQL,no-SQL,文件系统,外部API,FTP,SSH等。如果您试图在模型中完成所有这些工作,您最终会创build难以升级和debugging的复杂且难以理解的代码。
现在你想要做的是让模型从一个知道在哪里以及如何获取它的层获取数据,但是你的模型只使用API方法,例如fetch
, save
, delete
等等。在这个层内部,你有特定的具体实现数据提供者。 例如,您可以从本地机器上的PHP文件,Facebook API或Amazon AWS或远程HTML文档等请求某些数据。
PS其中的一些想法是从Cloud9的 架构师那里借用的: http : //events.yandex.ru/talks/300/
我把它设置为农场和文档描述。
但我有另外的问题,在我的实例方法和类方法,我将附加到每个函数中的模型,我将需要索引文件来获得其他数据库对象的持有。
通过让所有模型都可以访问来解决这个问题。
var Config = require('../config/config'); var fs = require('fs'); var path = require('path'); var Sequelize = require('sequelize'); var _ = require('lodash'); var sequelize; var db = {}; var dbName, dbUsername, dbPassword, dbPort, dbHost; // set above vars var sequelize = new Sequelize(dbName, dbUsername, dbPassword, { dialect: 'postgres', protocol: 'postgres', port: dbPort, logging: false, host: dbHost, define: { classMethods: { db: function () { return db; }, Sequelize: function () { return Sequelize; } } } }); fs.readdirSync(__dirname).filter(function(file) { return (file.indexOf('.') !== 0) && (file !== 'index.js'); }).forEach(function(file) { var model = sequelize.import(path.join(__dirname, file)); db[model.name] = model; }); Object.keys(db).forEach(function(modelName) { if ('associate' in db[modelName]) { db[modelName].associate(db); } }); module.exports = _.extend({ sequelize: sequelize, Sequelize: Sequelize }, db);
并在模型文件中
var classMethods = { createFromParams: function (userParams) { var user = this.build(userParams); return this.db().PromoCode.find({where: {name: user.promoCode}}).then(function (code) { user.credits += code.credits; return user.save(); }); } }; module.exports = function(sequelize, DataTypes) { return sequelize.define("User", { userId: DataTypes.STRING, }, { tableName: 'users', classMethods: classMethods }); };
我只为类方法做了这个,但你也可以为实例方法做同样的事情。
我遵循官方指南: http : //sequelizejs.com/heroku ,它有一个模型文件夹,将每个模块设置在不同的文件中,并有一个索引文件来导入它们并设置它们之间的关系。
您可以使用sequelize.import
从其他文件导入模型http://sequelizejs.com/documentation#models-import
这样,你可以有一个单体模块sequelize,然后加载所有其他模型。
其实这个答案是非常相似的user1778770的答案。
我正在寻找一个使用序列化ORM的示例nodejs应用程序。
您可能有兴趣查看PEAN.JS样板解决scheme。
PEAN.JS是一个完整的JavaScript开源解决scheme,它为基于PostgreSQL,Node.js,Express和AngularJS的应用程序提供了坚实的起点。
PEAN项目是MEAN.JS项目的一个分支(不要与MEAN.IO或通用 MEAN栈混淆)。
PEAN用PostgreSQL和SequelizereplaceMongoDB和Mongoose ORM。 MEAN.JS项目的主要优点是它提供了一个有许多移动块的堆栈。
你也可以使用dependency injection来提供一个优雅的解决scheme。 这里有一个https://github.com/justmoon/reduct
- 将preg_replace()e修饰符replace为preg_replace_callback
- Javascript + Unicode正则expression式
- Learning Express for Node.js
- 将Javastring从全部大写字母(由下划线分隔的string)转换为CamelCase(无字分隔符)的最简单方法是什么?
- 你如何从Linux文件中使用正则expression式提取IP地址?
- PostgreSQL的正则expression式边界?
- 结合两个expression式(Expression <Func <T,bool >>)
- grep使用具有多种模式的字符向量
- 从MySQL中的分层数据生成基于深度的树(无CTE)