在 Sequelize 迁移中创建关联

Evg*_*Gil 4 node.js sequelize.js

节点。续集 4.41。尝试通过另一个表制作具有多对多关系的 2 个模型。例如,使用sequelize-cli运行...

sequelize model:generate --name Camera --attributes name:string,sn:string
Run Code Online (Sandbox Code Playgroud)

这里是模型

// Camera model

'use strict';

module.exports = (sequelize, DataTypes) => {
  const ?amera = sequelize.define('?amera', {
    name: DataTypes.STRING,
    sn: DataTypes.STRING
  }, {});
  ?amera.associate = function(models) {
    // associations can be defined here
      Camera.belongsToMany(models.Relay, {through: 'CameraRelay'});
  };
  return ?amera;
};
Run Code Online (Sandbox Code Playgroud)

和

// Relay model

'use strict';

module.exports = (sequelize, DataTypes) => {
  const Relay = sequelize.define('Relay', {
    name: DataTypes.STRING,
    sn: DataTypes.STRING,
    channel: DataTypes.INTEGER
  }, {});
  Relay.associate = function(models) {
    // associations can be defined here
      Relay.belongsToMany(models.Camera, {through: 'CameraRelay'});
  };
  return Relay;
};
Run Code Online (Sandbox Code Playgroud)

在文档中有短语

Belongs-To-Many 关联用于连接具有多个目标的源。此外,目标还可以连接到多个源。

Project.belongsToMany(User, {through: 'UserProject'}); User.belongsToMany(Project, {through: 'UserProject'});

这将 使用等效的外键 projectId 和 userId创建一个名为 UserProject 的新模型。

迁移是

// create-relay

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Relays', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      sn: {
        type: Sequelize.STRING
      },
      channel: {
        type: Sequelize.INTEGER
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Relays');
  }
};
Run Code Online (Sandbox Code Playgroud)

和

//create camera
'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('?ameras', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      sn: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('?ameras');
  }
};
Run Code Online (Sandbox Code Playgroud)

为什么它不创建模型 CameraRelay 并且在我运行迁移时不为同一模型创建迁移?

nap*_*der 6

我想误解是关于同步与迁移:您所指的文档的很大一部分是使用同步方法从模型开始创建所有表和关联。

当您使用migrations 时,您正在使用迁移文件创建所有表/列/关联的数据库(并且在我看来,这是用于生产的东西的更好方法)。

要了解差异,只需查看您的相机型号与相机迁移文件:

  • 模型只定义了name和sn属性
  • 迁移文件当然有nameand sn,但也有id, createdAtand updatedAt。

迁移文件旨在以安全的方式更改您的数据库,允许您回滚到过去的任何时间点。

所以,回到你的问题,你必须:

  • 创建一个新的迁移文件来创建新的 CameraRelay 表,其中包含 Camera 和 Relay 表的外键
  • 使用与 CameraRelay 表的一对多关系更新您当前的相机迁移文件
  • 使用与 CameraRelay 表的一对多关系更新当前的 Relay 迁移文件

CameraRelay 迁移示例:

    'use strict';
    module.exports = {
      up: (queryInterface, Sequelize) => {
        return queryInterface.createTable('CameraRelays', {
          cameraId: {
            primaryKey: true,
            type: Sequelize.INTEGER,
            allowNull: false,
            references: {        
              model: 'Relay',
              key: 'id'
            }
          },
          relayId: {
            primaryKey: true,
            type: Sequelize.INTEGER,
            allowNull: false,
            references: {         
              model: 'Camera',
              key: 'id'
            }
          },
          createdAt: {
            allowNull: false,
            type: Sequelize.DATE
          },
          updatedAt: {
            allowNull: false,
            type: Sequelize.DATE
          }
        });
      },
      down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable('CameraRelays');
      }
    };

Run Code Online (Sandbox Code Playgroud)