续集如何运作? [英] How sequelize works?
问题描述
我试图通过一个简单的例子来理解 sequelize 是如何工作的:用户可以有很多帖子,而帖子只能有一个用户.
第一个问题,我不知道我是否必须使用迁移或同步模型来创建我的数据库.我的意思是,我必须在两者中放置相同的代码.这是用户表的迁移:
module.exports = {up: (queryInterface, Sequelize) =>{返回 queryInterface.createTable('用户', {ID: {allowNull: 假,自动增量:真,主键:真,类型:Sequelize.INTEGER},用户名: {allowNull: 假,类型:Sequelize.STRING,独特:真实},密码: {allowNull: 假,类型:Sequelize.STRING},电子邮件: {allowNull: 假,类型:Sequelize.STRING,独特:真实},创建于:{allowNull: 假,类型:Sequelize.DATE},更新于:{allowNull: 假,类型:Sequelize.DATE}});},向下: (queryInterface, Sequelize) =>{return queryInterface.dropTable('Users');}};
这是 Post 模型:
'use strict';module.exports = (sequelize, DataTypes) =>{const User = sequelize.define('User', {用户名:DataTypes.STRING,密码:DataTypes.STRING,电子邮件:DataTypes.STRING}, {类方法:{助理:(模型)=>{User.hasMany(models.Post);}}});返回用户;};
我是否还必须指定用户名、电子邮件不能为空并且在模型中必须是唯一的?
我该如何添加外键?在一个教程中,他们说数据库会自动添加外键,但如果我使用迁移,我认为它不起作用,我必须手动设置它不是吗?
对于你的版本 "sequelize": "^4.13.2":
classMethods 和 instanceMethods 被移除.
上一个:
const Model = sequelize.define('Model', {...}, {类方法:{关联:功能(模型){...}},实例方法:{someMethod: function () { ...}}});
新:
const Model = sequelize.define('Model', {...});//类方法Model.associate = 函数(模型){...关联模型};//实例方法Model.prototype.someMethod = function () {..}
查看官方文档升级到 V4
<小时>因此对于关系,您应该完成以下步骤:
- 导入模型
- 调用类associate"方法(如果存在)
- 导出
示例:
//模型/index.js从 'fs' 导入 fs;从路径"导入路径;从续集"导入续集;从'./config'导入配置;const sequelize = new Sequelize(config.db.url, config.db.options);const DB = {};//导入模型FS.readdirSync(__dirname).filter(file => (file.indexOf('.') !== 0) && (file !== path.basename(__filename)) && (file.slice(-3) ==='.js')).forEach((文件) => {const 模型 = sequelize.import(path.join(__dirname, file));DB[model.name] = 模型;});//这里你应该调用关联的类方法Object.keys(DB).forEach((modelName) => {if ('associate' in DB[modelName]) {DB[modelName].associate(DB);}});DB.sequelize = 续集;DB.Sequelize = 续集;导出默认数据库;
您可以放入模型中的所有关系.
用户:
//模型/user.js导出默认值(续集,数据类型)=>{const 用户 = sequelize.define('用户',//字段{ID: {类型:DataTypes.INTEGER,主键:真,自动增量:真,},//等等 ...},//选项{timestamps: false,//<-- 关闭时间戳underscored: true,//<-- 这个选项用下划线命名.示例:createdAt ->created_at证实: {},索引:[],},);User.associate =(模型)=>{User.hasMany(models.post, {//...});User.hasMany(models.comment, {//...});//或者models.user.hasMany(models.post, {//...});};返回用户;};
发布:
//模型/post.js导出默认值(续集,数据类型)=>{const Post = sequelize.define('帖子',//字段{//...},//选项{//...},);Post.associate =(模型)=>{Post.belongsTo(models.user, {//...});//或者模型.post.belongsTo(模型.用户,{//...});};回邮;};
<小时><块引用>
我是否还必须指定用户名、电子邮件不能为空和在模型中必须是唯一的吗?
是的,您应该定义模型中的所有内容,例如键、关系等.因为您的应用使用模型来执行数据库操作.
<小时><块引用>我该如何添加外键?在一个教程中,他们说我认为数据库会自动添加外键,但我不认为如果我使用迁移,它会起作用,我必须手动设置它吗?
实际上你不能在创建表和字段的迁移中定义复合键.
迁移的最佳实践应该是这样的:
- 000000_create_users_table
- 000001_add_foreign_keys_to_users_table
- 000002_add_new_field_to_users_table
- 等等...
所以你应该在迁移中手动添加所有内容.
要在迁移中添加索引,您应该使用 queryInterface.addIndex
module.exports = {向上:queryInterface =>queryInterface.addIndex('用户',{独特:真实,字段:['用户名','电子邮件'],//如果你想重命名你可以使用://名称:'随便'//按照惯例,默认名称将为:table_field1_fieldN},),向下:queryInterface =>queryInterface.removeIndex('用户','users_username_email',//<-- 这个名字是约定俗成的,但你可以重命名),};
<小时>
对于密钥",您应该使用 queryInterface.addConstraint
主键
queryInterface.addConstraint('用户', ['用户名'], {类型:'主键',名称:'custom_primary_constraint_name'});
外键
queryInterface.addConstraint('Posts', ['username'], {类型:'外键',name: 'custom_fkey_constraint_name',参考:{//必填字段表:'target_table_name',字段:'target_column_name'},onDelete: '级联',onUpdate: '级联'});
<小时>
检查所有API参考
I'm trying to understand how sequelize works on a simple example : User can have many posts and post can have only one user.
First question, I don't know if I have to use the migrations or the models with sync for creating my database. I mean, I have to put bearly the same code in both. This is the migration for the users table:
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');
}
};
And this is the Post model :
'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;
};
Do I also have to specify that the username, email can't be null and must be unique here in the model?
And how do I have to add the foreign key ? In one tutorial, they said me that the database add automaticly the foreign key but I don't think it works if I use the migrations, I have to set it manualy no?
For your version "sequelize": "^4.13.2":
classMethods and instanceMethods are removed.
Previous:
const Model = sequelize.define('Model', {
...
}, {
classMethods: {
associate: function (model) {...}
},
instanceMethods: {
someMethod: function () { ...}
}
});
New:
const Model = sequelize.define('Model', {
...
});
// Class Method
Model.associate = function (models) {
...associate the models
};
// Instance Method
Model.prototype.someMethod = function () {..}
See official docs Upgrade to V4
So for relations u should walkthrough this steps:
- Import models
- Call class "associate" method if exists
- Export
Example:
// 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;
All relations u can put in your models.
User:
// 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;
};
Do I also have to specify that the username, email can't be null and must be unique here in the model?
Yes u should define all things in your models, such as keys, relations, whatever. Because your app use models for actions with database.
And how do I have to add the foreign key ? In one tutorial, they said me that the database add automaticly the foreign key but I don't think it works if I use the migrations, I have to set it manualy no?
Actually u cant define composite keys in migrations that creates the table and fields.
Best practise for migrations should be like this:
- 000000_create_users_table
- 000001_add_foreign_keys_to_users_table
- 000002_add_new_field_to_users_table
- etc...
So u should add all things manually in migrations.
For adding indexes in migrations you should use 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
),
};
For "keys" you should use queryInterface.addConstraint
Primary Key
queryInterface.addConstraint('Users', ['username'], {
type: 'primary key',
name: 'custom_primary_constraint_name'
});
Foreign Key
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'
});
Check all API References
这篇关于续集如何运作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!