mysql - 未处理的拒绝 SequelizeDatabaseError : Foreign Key constraint error : cannot add foreign key

标签 mysql node.js sequelize.js

var state = require('./state')
module.exports = function (sequelize, DataTypes) {
    var city = sequelize.define('city', {
        city_id : {
            type : DataTypes.INTEGER,
            autoIncrement : true,
            primaryKey : true
        },
        city_name : {
            type : DataTypes.STRING,
            allowNull : false,
            unique : true
        },
        city_state_id : {
            type : DataTypes.INTEGER,
            allowNull : false,
            references : {
                model : 'states',
                key : 'state_id'
            }
        }
    }
    return  city;
}

这是我的引用文件。

module.exports = function (sequelize, DataTypes) {
    var state = sequelize.define('state', {
        state_id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        state_name: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        },
    })
    return state;
}

我不知道为什么我不能在这里添加外键约束。有人可以帮我吗?我收到这样的错误:

未处理的拒绝 SequelizeDatabaseError: ER_CANNOT_ADD_FOREIGN: 无法添加外键约束 当我尝试在终端上执行 migration.js 时:node migration.js

迁移.js :

 /*jslint node: true */
 'use strict';
 var Sequelize = require('sequelize');
 var fs = require('fs');
 var schema_dir = './schema/';
 var config = require('./config').mysql_conf;
 var connection = new Sequelize(config.database, config.username, config.password, config);
 fs.readdir(schema_dir, function(err, files) {
     if (err) {
         console.log(err);
     } else {
         files = files.sort();
         console.log(files);
         for (var i = 0; i < files.length; i++) {
             var module_name = files[i].slice(0, -3);
             console.log(schema_dir + files[i]);
             //  var schema = require(schema_dir + module_name);
             try {
                 var model = connection['import']('' + schema_dir + module_name);
                 model.sync().then(function() {
                     console.log("table created: " + module_name);
                 });
                 model.sync({force : true})
             } catch (ex) {
                 console.log("error with module_name: " + module_name, ex);
             }
         }
     }

 });

有人知道为什么会这样吗?

最佳答案

需要了解/修复几件事以确保其正常工作。

sync() 与 sync({force: true})

sync() 将运行 CREATE TABLE IF NOT EXISTSsync({force: true}) 将运行 DROP TABLE IF EXISTS 然后再次创建表。因此,这种迁移方法不适适用于 local/dev 以上的环境。此外,如果您想创建列、更改数据类型等,您不能使用这些方法来应用您的更改。

使用它在本地进行测试,然后通过SHOW CREATE TABLE 创建迁移文件并通过Sequelize migration 运行这些文件.

同步的异步性质

sync()具有讽刺意味的是异步的,这意味着同步循环并不能保证每个模型都按顺序加载。这可以输出不同的错误日志并让您失望。你应该使用像 async 这样的异步处理模块:

async.eachSeries(files, function(file, callback) {
    var model = require(currentDir + '/' + file);
    model
        .sync({force: true})
        .then(function() {
            console.log('Force-synced %s', file);
            callback();
        })
        .catch(callback);
}, function(err) {
    if(err) throw err;
    console.log('Completed migration in order as such %o', files);
});

迁移文件顺序

您的文件名为 city.model.jsstate.model.js。由于 fs.readdir 将按字母顺序读取它们,

    city_state_id : {
        type : DataTypes.INTEGER,
        allowNull : false,
        references : {
            model : 'states',
            key : 'state_id'
        }
    }

无法引用表 states,因为它尚不存在。

您需要正确订购它们。一种方法是像这样创建一个订单数组:

var order = [
    'state',
    'city'
];

async.eachSeries(order, function(file, callback) {
    var model = require(currentDir + '/' + file + '.model.js');
    model
        .sync({force: true})
        .then(function() {
            console.log('Force-synced %s', file);
            callback();
        })
        .catch(callback);
}, function(err) {
    if(err) throw err;
    console.log('Completed migration in order as such %o', files);
});

其他人不会等待模型加载

如果您正在运行测试或服务器,它们可能会在模型加载之前开始尝试访问它们。 sync 的异步特性阻止了服务器等待模型加载。

解决方案是使用模型作为一种查询方式,而不是一种更改表结构的方式。这应该用于本地测试并使用 Sequelize migration进行更改。

关于mysql - 未处理的拒绝 SequelizeDatabaseError : Foreign Key constraint error : cannot add foreign key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40172216/

相关文章:

mysql批处理-执行语句和脚本

java - GWT 和 SQL - 没有合适的驱动程序

java - 如何从服务器端 Java 应用程序发送 XMPP 通知?

node.js - 无法以 express 方式发布到服务器

c# - MySQLDataReader 仅在行数较多时循环一次

php加入相似结果

使用 mocha 的 nodejs(连接)应用程序的 http 请求测试?

node.js - sails .js : How to return access token after user registration using sails-generate-auth?

sequelize.js - 如何在使用 sequelize js orm 的模型中不使用外键关系来获取嵌套的 JSON 数组?

javascript - Node JS Sequelize如何统计关联数据