续集如何运作? [英] How sequelize works?

查看:38
本文介绍了续集如何运作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过一个简单的例子来理解 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

<小时>

因此对于关系,您应该完成以下步骤:

  1. 导入模型
  2. 调用类associate"方法(如果存在)
  3. 导出

示例:

//模型/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(模型.用户,{//...});};回邮;};

<小时><块引用>

我是否还必须指定用户名、电子邮件不能为空和在模型中必须是唯一的吗?

是的,您应该定义模型中的所有内容,例如键、关系等.因为您的应用使用模型来执行数据库操作.

<小时><块引用>

我该如何添加外键?在一个教程中,他们说我认为数据库会自动添加外键,但我不认为如果我使用迁移,它会起作用,我必须手动设置它吗?

实际上你不能在创建表和字段的迁移中定义复合键.

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

  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 = {向上: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:

  1. Import models
  2. Call class "associate" method if exists
  3. 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:

  1. 000000_create_users_table
  2. 000001_add_foreign_keys_to_users_table
  3. 000002_add_new_field_to_users_table
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆