在一对多关系中Sequelize迁移错误150

Sequelize migration error 150 in one to many relationship

我将正在开发的 Web 应用程序从 Windows 克隆到 Ubuntu 机器中。此应用程序采用模块化结构,包括一个 Node JS 服务器、一个 MYSQL 数据库和一个带有 React 的客户端。

我正在为数据库控制器使用 Sequelize CLI。

当我在 Ubuntu 中创建数据库和 运行 迁移时,我得到

ERROR: Can't create table icsi_app_development.phases (errno: 150 "Foreign key constraint is incorrectly formed")

这在 Windows 中工作正常,具有相同的依赖关系:

Sequelize CLI [Node: 14.17.2, CLI: 6.2.0, ORM: 6.6.2]

知道这个关联错误吗?非常感谢!

这是我的作品-phase.js

'use strict';
module.exports = {
  up: async (queryInterface, DataTypes) => {
    await queryInterface.createTable('phases', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER
      },
      uuid: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4
      },
      projectId: {
        type: DataTypes.INTEGER,
        references: {model: "Projects", key: "id"},
        onDelete: "CASCADE"
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
      },
      description: {
        type: DataTypes.STRING,
        allowNull: false
      },
      isActive: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: true
      },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE
      }
    });
  },
  down: async (queryInterface, DataTypes) => {
    await queryInterface.dropTable('phases');
  }
};

这是我的作品-project.js

'use strict';
module.exports = {
  up: async (queryInterface, DataTypes) => {
    await queryInterface.createTable('projects', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER
      },
      uuid: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4
      },
      nume: {
        type: DataTypes.STRING,
        allowNull: false
      },
      cod_identificare: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
      },
      departament: {
        type: DataTypes.STRING,
        allowNull: false
      },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE
      }
    });
  },
  down: async (queryInterface, DataTypes) => {
    await queryInterface.dropTable('projects');
  }
};

这是我的项目模型

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Project extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
    // toJSON(){
    //   return {...this.get(), id: undefined}
    // }
  };
  Project.init({
    nume: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notNull: {msg: "Proiectul trebuie sa aiba un nume"},
        notEmpty: {msg: "Proiectul trebuie sa aiba un nume"}
      }
    },
    cod_identificare: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        notNull: {msg: "Proiectul trebuie sa prezinte un cod de identificare unic"},
        notEmpty: {msg: "Proiectul trebuie sa prezinte un cod de identificare unic"}
      }
    },
    departament: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notNull: {msg: "Proiectul trebuie sa fie atribuit unui departament"},
        notEmpty: {msg: "Proiectul trebuie sa fie atribuit unui departament"}
      }
    },
    uuid: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4
    }
  }, 
  {
    sequelize,
    tableName: "projects",
    modelName: 'Project',
  });

  Project.associate = (models) => {
    Project.hasMany(models.Phase, {
      foreignKey: 'projectId',
      as: "phases"
    });

    Project.belongsToMany(models.User, {
      foreignKey: 'projectId',
      through: 'users_projects',
      as: "users"
    });
  }

  return Project;
};

这是我的相位模型

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Phase extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  };
  Phase.init({
    projectId: {
      type: DataTypes.INTEGER,
      allowNull: false
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        notEmpty: {msg: "Faza proiectului trebuie sa prezinte un titlu"},
        notNull: {msg: "Faza proiectului trebuie sa prezinte un titlu"}
      }
    },
    description: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notEmpty: {msg: "Faza proiectului trebuie sa prezinte o descriere"},
        notNull: {msg: "Faza proiectului trebuie sa prezinte o descriere"}
      }
    },
    isActive: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      defaultValue: true
    },
    uuid: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4
    }
  }, {
    sequelize,
    tableName: "phases",
    modelName: 'Phase',
  });

  Phase.associate = (models) => {
    Phase.belongsTo(models.Project, {
      foreignKey: 'projectId',
      as: "projects"
    });

    Phase.hasMany(models.File, {
      foreignKey: "phaseId",
      as: "files"
    });
  }

  return Phase;
};

我突然想到有两件事是错误的可能性。

  1. 如果您是 运行 在项目 table 之前创建阶段 table 的迁移,我相信您会遇到这个问题。在软件引用项目 table 及其 id 列之前,您将创建一个 projectId 外键。

  2. 大写在 SQL 中通常不是问题,但 Sequelize 可能在 Projects 迁移和“Projects”的 createTable 方法中遇到“projects”不同大写的问题在阶段迁移中 projectId.references 的模型 属性 中。