在Sequelize迁移中创建关联

时间:2018-11-13 19:47:09

标签: node.js sequelize.js

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

sequelize model:generate --name Camera --attributes name:string,sn:string

这是模特

// 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;
};

// 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;
};

在文档中有短语

  

“多对多”关联用于连接具有多个目标的源。此外,目标还可以与多个源建立连接。

     

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

     

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

迁移是

// 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');
  }
};

//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');
  }
};

为什么在运行迁移时它不会创建CameraRelay模型,也不会为同一模型创建迁移?

1 个答案:

答案 0 :(得分:0)

我猜误解是关于 sync migration :您所指的文档中很大一部分是使用 sync 方法创建的从模型开始的所有表和关联。

在使用迁移时,您正在使用迁移文件创建所有表/列/关联的数据库(在我看来,这是将要生产的更好的方法)

要了解它们之间的区别,只需查看您的相机型号与相机迁移文件:

  • 该模型仅定义了namesn属性
  • 迁移文件当然有namesn,但也有idcreatedAtupdatedAt

迁移是一种文件,旨在以安全的方式更改数据库,使您可以回滚到过去的任何时间。

因此,回到您的问题,您必须:

  • 创建一个新的迁移文件以创建新的CameraRelay表,并同时使用Camera和Relay表的外键
  • 通过与CameraRelay表一对多的关系更新当前的Camera迁移文件
  • 使用与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');
      }
    };