update tutorial node framework ejemplos actualizar node.js express sequelize.js

node.js - tutorial - npm



¿Cómo organizar una aplicación de nodo que utiliza la secuenciación? (10)

Estoy buscando un ejemplo de la aplicación nodejs que utiliza la secuencia de ORM.

Puede que le interese consultar la solución estándar de PEAN.JS.

PEAN.JS es una solución de código abierto de JavaScript de pila completa, que proporciona un punto de partida sólido para las aplicaciones basadas en PostgreSQL, Node.js, Express y AngularJS.

El proyecto PEAN es una bifurcación del proyecto MEAN.JS (que no debe confundirse con MEAN.IO o la pila genérica MEAN).

PEAN reemplaza a MongoDB y a Mongoose ORM con PostgreSQL y Sequelize. Un beneficio principal del proyecto MEAN.JS es la organización que proporciona a una pila que tiene muchas piezas móviles.

Estoy buscando un ejemplo de la aplicación nodejs que utiliza la secuencia de ORM.

Mi principal preocupación es que parece casi imposible definir sus modelos en archivos js separados si esos modelos tienen relaciones complejas entre sí debido a los bucles de dependencia require (). ¿Tal vez las personas definen todos sus modelos en un archivo que es muy largo?

Me interesa principalmente cómo se definen y usan los modelos a través de la aplicación. Me gustaría tener alguna confirmación de que lo que estoy haciendo por mi cuenta es la "buena" manera de hacer las cosas.


La historia corta

El truco en este caso no es inicializar el modelo en el archivo sino solo proporcionar la información necesaria para su inicialización y dejar que un módulo centralizado se encargue de la configuración e instanciación de los modelos.

Entonces los pasos son:

  • Tenga varios archivos de modelo con datos sobre el modelo, como campos, relaciones y opciones.
  • Tenga un módulo singleton que cargue todos esos archivos y configure todas las clases y relaciones del modelo.
  • Configure su módulo singleton en el archivo app.js.
  • Obtenga las clases modelo del módulo singleton no use require en sus archivos modelo, cargue los modelos desde el singleton en su lugar.

La historia más larga

Aquí hay una descripción más detallada de esta solución con el código fuente correspondiente:

http://jeydotc.github.io/blog/2012/10/30/EXPRESS-WITH-SEQUELIZE.html

EDITAR: ¡Esta es una respuesta muy antigua! (leer para obtener información)

¡Es viejo y limitado de muchas maneras!

  • En primer lugar , como lo mencionó @jinglesthula en los comentarios (y yo también lo experimenté), existen problemas al requerir esos archivos. ¡Es porque require no funciona de la misma manera que readdirSync !

  • En segundo lugar , tiene relaciones muy limitadas, el código no proporciona opciones para esas asociaciones, por lo que no puede crear belongsToMany como lo necesita a through propiedad. Puedes hacer las asociaciones más básicas.

  • Tercero , ¡estás muy limitado en las relaciones modelo! Si lees detenidamente el código, verás que las relaciones son un Objeto en lugar de una Matriz , así que si quieres hacer más de una asociación del mismo tipo (como tener dos veces belongsTo ), ¡no puedes!

  • Cuarto : No necesitas esa cosa única. Cada módulo en nodejs es singleton por sí mismo, por lo que todo esto es bastante complejo sin ningún motivo.

¡Deberías ver la respuesta de Farm! (El enlace al artículo está roto, pero lo arreglaré con esta muestra oficial de la secuencia: https://github.com/sequelize/express-example/blob/master/models/index.js - puede navegar por proyecto completo para tener una idea de lo que está pasando).

ps. Estoy editando esta publicación, ya que está tan votada que las personas ni siquiera verán nuevas respuestas (como yo lo hice).

Editar: acaba de cambiar el enlace a una copia de la misma publicación, pero en una página de Github


Empecé a usar Sequelize en la aplicación Express.js. Muy pronto se encontraron con problemas de la naturaleza que describes. Tal vez no entendí completamente Sequelize, pero para mí hacer cosas más que simplemente seleccionar de una mesa no era realmente conveniente. Y donde normalmente usarías seleccionar de dos o más tablas, o una unión en SQL puro, tendrías que ejecutar consultas separadas, y con la naturaleza asincrónica de Node solo se agrega complejidad.

Por lo tanto, me alejé del uso de Sequelize. Además, estoy cambiando el uso de CUALQUIER captura de datos de DB en los modelos. En mi opinión, es mejor abstraer la obtención de datos por completo. Y las razones son - imagina que no solo usas MySQL (en mi caso, uso MySQL y MongoDB uno al lado del otro), sino que puedes obtener tus datos de cualquier proveedor de datos y cualquier método de transporte, por ejemplo SQL, no SQL, sistema de archivos, API externa, FTP, SSH, etc. Si intentaba hacer todo eso en los modelos, eventualmente crearía un código complejo y difícil de entender que sería difícil de actualizar y depurar.

Ahora lo que quiere hacer es que los modelos obtengan datos de una capa que sabe dónde y cómo obtenerlos, pero sus modelos solo usan métodos API, por ejemplo, fetch , save , delete , etc. Y dentro de esta capa tiene implementaciones específicas para casos específicos. proveedores de datos. Por ejemplo, puede solicitar ciertos datos desde un archivo PHP en una máquina local o desde Facebook API o desde Amazon AWS o desde un documento HTML remoto, etc.

PD: algunas de estas ideas fueron tomadas de Architect by Cloud9 : http://events.yandex.ru/talks/300/


Estoy siguiendo la guía oficial: http://sequelizejs.com/heroku , que tiene una carpeta de modelos, configura cada módulo en archivos separados y tiene un archivo de índice para importarlos y establecer la relación entre ellos.


Lo configuré como Farm y la documentación describe.

Pero estaba teniendo el problema adicional de que en mis métodos de instancia y métodos de clase que adjuntaría a los modelos en cada función necesitaría requerir que el archivo de índice controle otros objetos de la base de datos.

Lo resolvió haciéndolos accesibles a todos los modelos.

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);

Y en el archivo de modelo

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 }); };

Solo hice esto para los métodos de clase, pero también podría hacer lo mismo para los métodos de ejemplo.


Puede importar modelos de otros archivos con sequelize.import http://sequelizejs.com/documentation#models-import

De esta forma, puede tener un módulo singleton para la secuenciación, que luego carga todos los demás modelos.

En realidad, esta respuesta es bastante similar a la respuesta del usuario1778770.


Secuencia de modelo de muestra

''use strict''; const getRole = require(''../helpers/getRole'') const library = require(''../helpers/library'') const Op = require(''sequelize'').Op module.exports = (sequelize, DataTypes) => { var User = sequelize.define(''User'', { AdminId: DataTypes.INTEGER, name: { type: DataTypes.STRING, validate: { notEmpty: { args: true, msg: ''Name must be filled !!'' }, } }, email: { type: DataTypes.STRING, validate: { notEmpty: { args: true, msg: ''Email must be filled !!'' }, isUnique: function(value, next) { User.findAll({ where:{ email: value, id: { [Op.ne]: this.id, } } }) .then(function(user) { if (user.length == 0) { next() } else { next(''Email already used !!'') } }) .catch(function(err) { next(err) }) } } }, password: { type: DataTypes.STRING, validate: { notEmpty: { args: true, msg: ''Password must be filled !!'' }, len: { args: [6, 255], msg: ''Password at least 6 characters !!'' } } }, role: { type: DataTypes.INTEGER, validate: { customValidation: function(value, next) { if (value == '''') { next(''Please choose a role !!'') } else { next() } } } }, gender: { type: DataTypes.INTEGER, validate: { notEmpty: { args: true, msg: ''Gender must be filled !!'' }, } }, handphone: { type: DataTypes.STRING, validate: { notEmpty: { args: true, msg: ''Mobile no. must be filled !!'' }, } }, address: DataTypes.TEXT, photo: DataTypes.STRING, reset_token: DataTypes.STRING, reset_expired: DataTypes.DATE, status: DataTypes.INTEGER }, { hooks: { beforeCreate: (user, options) => { user.password = library.encrypt(user.password) }, beforeUpdate: (user, options) => { user.password = library.encrypt(user.password) } } }); User.prototype.check_password = function (userPassword, callback) { if (library.comparePassword(userPassword, this.password)) { callback(true) }else{ callback(false) } } User.prototype.getRole = function() { return getRole(this.role) } User.associate = function(models) { User.hasMany(models.Request) } return User; };



SequelizeJS tiene un artículo en su sitio web que resuelve este problema.

El enlace está roto, pero puede encontrar el proyecto de muestra de trabajo here y explorarlo. Vea la respuesta editada arriba para ver por qué esta es una solución mejor.

Extracto del artículo:

  • models / index.js

    La idea de este archivo es configurar una conexión a la base de datos y recopilar todas las definiciones del Modelo. Una vez que todo esté en su lugar, llamaremos al método asociado en cada uno de los Modelos. Este método se puede usar para asociar el Modelo con otros.

    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)


sequelize-connect un paquete sequelize-connect para ayudar a las personas a lidiar con este problema. Sigue la convención sugerida de Sequelize aquí: http://sequelize.readthedocs.org/en/1.7.0/articles/express/

Además, también funciona un poco más como Mongoose en términos de su interfaz. Le permite especificar un conjunto de ubicaciones donde se encuentran sus modelos y también le permite definir una función de coincidencia personalizada para que coincida con los archivos de su modelo.

El uso es básicamente así:

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

Luego puede acceder a los modelos y realizar la secuencia de la siguiente manera:

var orm = require(''sequelize-connect''); var sequelize = orm.sequelize; var Sequelize = orm.Sequelize; var models = orm.models; var User = models.User;

Espero que esto ayude a alguien a salir.