sequelize 中的引用字段是啥?

Posted

技术标签:

【中文标题】sequelize 中的引用字段是啥?【英文标题】:What is the references field for in sequelize?sequelize 中的引用字段是什么? 【发布时间】:2020-07-22 09:24:29 【问题描述】:

我有一个用户表,其中包含角色表的外键列。

我在 mysql 中定义了所有关系并使用sequelize-auto 生成了我的模型。

为用户生成的模型是这样的:

  const user = sequelize.define('user', 
    Id: 
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
    ,
    Email: 
      type: DataTypes.STRING(45),
      allowNull: false,
      unique: true,
    ,
    RoleId: 
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: 
        model: 'roles',
        key: 'Id',
      ,
    ,
  );

我认为我的引用已设置,因此当我在解析器中执行以下操作时:

users: async () => 
  const users = await db.user.findAll(
    include: [
      
        model: db.roles,
      ,
    ],
  );

return users

我应该在操场上使用以下查询返回用户角色列表:

users
  roles
   Name, Id
  

我得到了

角色未与用户关联!

后来我发现我需要建立一个关联:

  user.associate = models => 
    user.hasMany(models.roles, 
      foreignKey: 'Id',
      sourceKey: 'RoleId',
      onDelete: 'cascade',
    );
  ;

然后它起作用了。

我还是不明白,这在用户模型中有什么用?:

 references: 
    model: 'roles',
    key: 'Id',
  ,

我认为这是我与角色表的“关联”,但没有我明确添加关联,这根本没有任何作用。有人可以解释references字段的含义吗?

【问题讨论】:

【参考方案1】:

给定的答案是正确的,但后来我意识到这个问题的原因是我认为我可以通过代码创建关联,这样我就不必默认手动修改每个模型。

对于那些想要做同样事情的人,我找到了一个解决方案 here。

基本上是:

1) 在您的模型文件夹中创建一个 index.js 文件并添加以下代码

import Sequelize from 'sequelize';

const fs = require('fs');
const path = require('path');

const basename = path.basename(__filename);

const db = ;

// @ts-ignore
const sequelize = new Sequelize('dbname', 'dbUser', 'password', 
  host: '127.0.0.1',
  port: 'PORT',
  dialect: 'mysql',
  define: 
    freezeTableName: true,
    timestamps: false,
  ,
  pool: 
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000,
  ,
  // <http://docs.sequelizejs.com/manual/tutorial/querying.html#operators>
  operatorsAliases: false,
);

const tableModel = ;

fs.readdirSync(__dirname)
  .filter(file => file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js')
  .forEach(file => 
    const model = sequelize.import(path.join(__dirname, file));
    db[model.name] = model;
    tableModel[model.name] = model;
  );

Object.getOwnPropertyNames(db).forEach(modelName => 
  const currentModel = db[modelName];
  Object.getOwnPropertyNames(currentModel.rawAttributes).forEach(attributeName => 
    if (
      Object.prototype.hasOwnProperty.call(
        currentModel.rawAttributes[attributeName],
        'references'
      ) &&
      Object.prototype.hasOwnProperty.call(
        currentModel.rawAttributes[attributeName].references,
        'model'
      ) &&
      Object.prototype.hasOwnProperty.call(
        currentModel.rawAttributes[attributeName].references,
        'key'
      )
    ) 
      if (
        !(
          currentModel.rawAttributes[attributeName].references.model &&
          currentModel.rawAttributes[attributeName].references.key
        )
      ) 
        console.log(
          `*SKIPPED* $modelName $attributeName references a model $currentModel.rawAttributes[attributeName].references.model with key $currentModel.rawAttributes[attributeName].references.key`
        );
        return;
      

      console.log(
        `$modelName $attributeName references a model $currentModel.rawAttributes[attributeName].references.model with key $currentModel.rawAttributes[attributeName].references.key`
      );
      const referencedTable =
        tableModel[currentModel.rawAttributes[attributeName].references.model];

      currentModel.belongsTo(referencedTable,  foreignKey: attributeName );
      referencedTable.hasMany(currentModel,  foreignKey: attributeName );

    
  );
);

// @ts-ignore
db.sequelize = sequelize;
// @ts-ignore
db.Sequelize = Sequelize;

// eslint-disable-next-line eol-last
module.exports = db;

2) 在您的解析器内部只需参考上述内容:

const db = require('../assets/models/index');

【讨论】:

【参考方案2】:

references 用于描述迁移中的模型以及使用同步功能自动创建表。要操作数据(不是结构),您可以使用 user.hasMany

之类的关联

【讨论】:

所以它是一个描述,但如果我只专注于在我的后端环境中实用并在 mysql 工作台中创建所有关系,那么这个字段对我来说没用吗?但是,如果我想从我的后端创建表到我的 mysql 环境,那么这有用吗? 如果您将使用迁移来创建和修改数据库结构,那么您根本不需要模型中的“引用”。所有这些引用都将在迁移中帮助后续 CLI 创建外键。 sequelize-auto 的当前版本 0.7.5 自动生成关联。

以上是关于sequelize 中的引用字段是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Sequelize.hasMany/belongsTo中的foreignKey是啥意思?

Sequelize - 自我引用有很多关系

关联类方法中的现有字段 sequelize

Sequelize - 将字段映射到模型定义中的字段别名

Sequelize:WHERE LIKE 子句中的 Concat 字段

Sequelize(或清除 SQL)查询以选择包含 JSON 字段中的值的行?