sequelize中的references字段是用来做什么的?

4

我有一个用户表,其中有一个外键列指向角色表。

我在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

我应该通过playground在以下查询中获得用户角色列表:

{users
  {roles
   {Name, Id}
  }
}

相反,我得到了:

角色未与用户关联!

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

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

然后它起作用了。

我仍然不明白用户模型中这个是干什么的?

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

我认为这是由于我与“roles”表的“关联”,但如果没有明确添加关联,则什么都不会发生。请问有人可以解释一下“references”字段的含义吗?

2个回答

2

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


那么,如果我只关注于在我的后端环境中实际创建所有关系,并在MySQL Workbench中进行,则这个字段对我来说是无用的,因为它只是一个描述?但是,如果我想要从我的后端创建表到MySQL环境中,那么这个字段就有用了? - CodingLittle
如果您使用迁移来创建和修改数据库结构,那么在模型中就不需要使用“references”了。所有这些引用将在迁移中存在,以帮助Sequelize CLI创建外键。 - Anatoly
1
sequelize-auto 的当前版本为 0.7.5,可以自动生成关联。 - Steve Schmitt

0
给出的答案是正确的,但后来我意识到这个问题的原因是我假设我可以通过代码创建关联,这样我就不必默认手动修改每个模型。
对于那些想要做同样事情的人,我在这里找到了一个解决方案。
基本上是:
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');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接