如何sequelize作品?

我试图了解sequelize如何工作在一个简单的例子:用户可以有很多post和post只能有一个用户。

第一个问题,我不知道是否必须使用迁移或同步模型来创build我的数据库。 我的意思是,我必须在两者中使用相同的代码。 这是用户表的迁移:

module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('Users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, username: { allowNull: false, type: Sequelize.STRING, unique: true }, password: { allowNull: false, type: Sequelize.STRING }, email: { allowNull: false, type: Sequelize.STRING, unique: true }, createdAt: { allowNull: false, type: Sequelize.DATE }, updatedAt: { allowNull: false, type: Sequelize.DATE } }); }, down: (queryInterface, Sequelize) => { return queryInterface.dropTable('Users'); } }; 

这是Post模式:

 'use strict'; module.exports = (sequelize, DataTypes) => { const User = sequelize.define('User', { username: DataTypes.STRING, password: DataTypes.STRING, email: DataTypes.STRING }, { classMethods: { associate: (models) => { User.hasMany(models.Post); } } }); return User; }; 

我是否还必须指定用户名,电子邮件不能为null,并且在模型中必须是唯一的?

我该如何添加外键? 在一篇教程中,他们说我数据库会自动添加外键,但是我不认为它使用迁移,我必须将它设置为manualy否?

对于你的版本“sequelize”:“^ 4.13.2”

classMethods和instanceMethods被删除。

以前:

 const Model = sequelize.define('Model', { ... }, { classMethods: { associate: function (model) {...} }, instanceMethods: { someMethod: function () { ...} } }); 

新:

 const Model = sequelize.define('Model', { ... }); // Class Method Model.associate = function (models) { ...associate the models }; // Instance Method Model.prototype.someMethod = function () {..} 

查看官方文档升级到V4


所以对于关系你应该通过这个步骤:

  1. 导入模型
  2. 调用类“关联”方法(如果存在)
  3. 出口

例:

 // models/index.js import fs from 'fs'; import path from 'path'; import Sequelize from 'sequelize'; import config from './config'; const sequelize = new Sequelize(config.db.url, config.db.options); const DB = {}; // Import models fs .readdirSync(__dirname) .filter(file => (file.indexOf('.') !== 0) && (file !== path.basename(__filename)) && (file.slice(-3) === '.js')) .forEach((file) => { const model = sequelize.import(path.join(__dirname, file)); DB[model.name] = model; }); // Here u should call class method for associations Object.keys(DB).forEach((modelName) => { if ('associate' in DB[modelName]) { DB[modelName].associate(DB); } }); DB.sequelize = sequelize; DB.Sequelize = Sequelize; export default DB; 

所有的关系都可以放在你的模型中。

用户:

 // models/user.js export default (sequelize, DataTypes) => { const User = sequelize.define( 'users', // Fields { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, // etc ... }, // Options { timestamps: false, // <-- turn off timestamps underscored: true, // <-- this option for naming with underscore. example: createdAt -> created_at validate: {}, indexes: [], }, ); User.associate = (models) => { User.hasMany(models.post, { // ... }); User.hasMany(models.comment, { // ... }); // OR models.user.hasMany(models.post, { // ... }); }; return User; }; 

post:

 // models/post.js export default (sequelize, DataTypes) => { const Post = sequelize.define( 'posts', // Fields { // ... }, // Options { // ... }, ); Post.associate = (models) => { Post.belongsTo(models.user, { // ... }); // OR models.post.belongsTo(models.user, { // ... }); }; return Post; }; 

我是否还必须指定用户名,电子邮件不能为null,并且在模型中必须是唯一的?

是的,你应该定义模型中的所有东西,比如键,关系等等。 因为您的应用程序使用数据库操作的模型。


我该如何添加外键? 在一篇教程中,他们说我数据库会自动添加外键,但是我不认为它使用迁移,我必须将它设置为manualy否?

实际上你不能在创build表和字段的迁移中定义组合键。

迁移的最佳实践应该是这样的:

  1. 000000_create_users_table
  2. 000001_add_foreign_keys_to_users_table
  3. 000002_add_new_field_to_users_table
  4. 等等…

所以你应该在迁移中手动添加所有的东西。

要在迁移中添加索引,应使用queryInterface.addIndex

 module.exports = { up: queryInterface => queryInterface.addIndex( 'users', { unique: true, fields: ['username', 'email'], // if u want to rename u can use: // name: 'whatever' // by convention default name will be: table_field1_fieldN }, ), down: queryInterface => queryInterface.removeIndex( 'users', 'users_username_email', // <-- this name by convention, but u can rename it ), }; 

对于“键”你应该使用queryInterface.addConstraint

首要的关键

 queryInterface.addConstraint('Users', ['username'], { type: 'primary key', name: 'custom_primary_constraint_name' }); 

外键

 queryInterface.addConstraint('Posts', ['username'], { type: 'FOREIGN KEY', name: 'custom_fkey_constraint_name', references: { //Required field table: 'target_table_name', field: 'target_column_name' }, onDelete: 'cascade', onUpdate: 'cascade' }); 

检查所有的API参考

你是对的,你必须手动设置外键关系。

这里是官方文档链接: http : //docs.sequelizejs.com/manual/tutorial/associations.html

你可以尝试下面的代码:

 var user_object = require('your_file_path'); var post_object = require('your_file_path'); user_object.hasMany(post_object, { foreignKey: 'user_id', sourceKey: 'user_id', onDelete: 'cascade', as:'Posts', }); post_object.belongsTo(user_object, { foreignKey: 'user_id', sourceKey: 'user_id', onDelete: 'cascade', as:'Posts', }); 

我真的只是重构你的代码。

//创build一个数据库configuration文件

 var Sequelize=require('sequelize'); var connection=new Sequelize('project','user','password',{ dialect:'mysql', logging:false }); connection.authenticate() .then(() => { console.log("Connected to database"); }) .catch(err => { //console.error("Can't connect to database :(\n", err); }); module.exports={ database:connection, } 

//您的用户架构文件

 var database = require('your_file_path/DatabaseConnection').database; var Sequelize = require('sequelize'); var Users = database.define('users', { username: { allowNull: false, type: Sequelize.STRING, unique: true }, password: { allowNull: false, type: Sequelize.STRING }, email: { allowNull: false, type: Sequelize.STRING, unique: true } }, { underscored: true },hooks: { beforeCreate: (user, option) => { users.password = encrypto.encryptEntity(user.password); //for automatic encryption of password }, } 

);

  Users.sync(); //id, updated_at , and modified_at will be maintained by default module.exports = { Users } 

//你的文章path

 var Posts = database.define('posts', { post_content: { allowNull: false, type: Sequelize.STRING, unique: true } }, { underscored: true }); //importing User var Users = require('file_path') Users.hasMany(Posts, { foreignKey: 'user_id', sourceKey: 'user_id', onDelete: 'cascade', as:'Posts', }); Posts.belongsTo(Users, { foreignKey: 'user_id', sourceKey: 'user_id', onDelete: 'cascade', as:'Users', }); // two way binding. Posts.sync(); 

通过维护关系,您可以使用setter和getter方法轻松更新数据

 Posts.setUsers(user_object); 

//上面的代码会自动将user_id中find的user_id

//对于您可以使用的select查询:

 Users.findOne({ where:{ id:user_id }, include: [{ model: Posts, attributes: ['post_content'], as: "Posts" }//this will bring every posts user has created }) 

我认为上面的编码标准将使您的代码看起来更清洁,并将对更大的项目更有帮助。

希望这可以帮助。