【问题标题】:Unable to insert id into a table that belongs to a foreign key referenced table using Sequelize无法使用 Sequelize 将 id 插入属于外键引用表的表中
【发布时间】:2018-10-12 09:30:08
【问题描述】:

我正在使用 node js 构建无服务器应用程序,并使用 claudia-api-builder 作为在 AWS 中启动 API 的框架。

在 app.js 文件中,我将所需的 api 称为

const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
module.exports = api;

api.post('/api/auth/validatephonenumber', async function (request) 
{
    return new Promise((resolve, reject) => {
        index.loadDatabase().then((db) => {
            resolve(loginController.validatePhonenumber(db, request));
        });
    });
});

下面是我的代码:

async function validatePhonenumber(db, request) {
return new Promise(
    async (resolve, reject) => {
        let emailid;            
        await db.EmailRegistration.sync().then(function () {
             emailid = db.EmailRegistration.findOne({
                where: { email: { [Op.eq]: mailid } },
                attributes: ['id'],
            });
        });
        if (emailid != null) {
            console.log(`email id: ${emailid.id}`);
            await db.ContactDetails.sync().then(function () {
                db.ContactDetails.findOrCreate({
                    where: { contactnumber: phnum },
                    defaults: { EmailRegistrationId: emailid.id },
                }).spread((contactdetails, created) => {
                    console.log(`contactdetails: ${contactdetails}`);
                    if (contactdetails !== null) {
                        resolve({ statuscode: indexController.statusCode.statusOK, contactdetails: contactdetails })
                    } else {
                        reject({ statuscode: indexController.statusCode.InternalServerError, message: 'phone number not created' });
                    }
                });
            });
        };
    });
}

我正在尝试将 EmailRegistration 表的 emailregistrationid 作为外键引用添加到 ContactDetails 表中。我正在使用 mysql、nodejs 的 sequelize 来达到预期的效果。但是,我得到以下错误:

未处理的拒绝 SequelizeForeignKeyConstraintError: 无法添加或更新子行:外键约束失败 (inmeeydb.ContactDetails, CONSTRAINT ContactDetails_ibfk_1 FOREIGN KEY (EmailRegistrationId) REFERENCES EmailRegistration (id) ON更新级联时删除级联)

以下是我的 EmailRegistration 模型文件:

const moment = require('moment');

module.exports = (sequelize, DataTypes) => {
const EmailRegistration = sequelize.define(
'EmailRegistration',
{
  id: {
    type: DataTypes.UUID,
    primaryKey: true,
    allowNull: false,
    defaultValue: DataTypes.UUIDV4,
  },
  email: {
    type: DataTypes.STRING(50),
    allowNull: false,
  },
  password: {
    type: DataTypes.STRING,
    allowNull: false,
    validate: { min: 6 },
  },
  createdAt: {
    type: DataTypes.DATE,
    get() {
      return moment.utc(new Date(), 'DD/MM/YYYY h:mm a').format('DD/MM/YYYY h:mm a');
    },
  },
  updatedAt: {
    type: DataTypes.DATE,
    defaultValue: null,       
  },
},
{
  freezeTableName: true,
}
);

EmailRegistration.associate = function (models) {
    EmailRegistration.hasOne(models.ContactDetails,
        { foreignKey: 'EmailRegistrationId' }
    );
};

return EmailRegistration;
};

下面是我的 Contactdetails 模型文件:

const moment = require('moment');

module.exports = (sequelize, DataTypes) => {
const ContactDetails = sequelize.define(
'ContactDetails',
{
  id: {
    type: DataTypes.UUID,
    primaryKey: true,
    allowNull: false,
    defaultValue: DataTypes.UUIDV4,
  },
  contactnumber: { type: DataTypes.STRING(13), allowNull: false },
  isverified: { type: DataTypes.BOOLEAN, defaultValue: false },
  createdAt: {
    type: DataTypes.DATE,
    get() {
      return moment.utc(new Date(), 'DD/MM/YYYY h:mm a').format('DD/MM/YYYY h:mm a');
    },
  },
  updatedAt: {
    type: DataTypes.DATE,
    defaultValue: null,        
  },
},
{
  indexes: [{ fields: ['contactnumber'], unique: true }],
},
{
  freezeTableName: true,
}
);

ContactDetails.associate = function(models) {
ContactDetails.belongsTo(models.EmailRegistration, {
  onDelete: 'CASCADE',
  hooks: true,
  foreignKey: { allowNull: false },
});
};   


return ContactDetails;
};

我尝试在两个表中参考以下代码更改代码,但没有任何效果。

ContactDetails.associate = function(models) {
    ContactDetails.belongsTo(models.EmailRegistration,
    { foreignKey: 'EmailRegistrationId' }
    );
};

无法分析如何解决该问题。当我将 nodejs 与 expressjs 一起使用并且没有问题时,这工作正常。它无法识别 ContactDetails 表中的 EmailRegistrationId(查询中缺少的),并将输出显示为

INSERT INTO `ContactDetails` (`id`,`contactnumber`,`isverified`,`createdAt`,`updatedAt`) VALUES ('52974e07-8489-4101-ab71-6af874903290','+xxxxxxxxx',false,'2018-10-12 08:55:35','2018-10-12 08:55:35');

【问题讨论】:

    标签: mysql node.js sequelize.js serverless claudia.js


    【解决方案1】:

    您需要更新关联的配置。 ContactDetails 模型现在将有一个名为 emailregistrationid 的字段

    EmailRegistration.associate = function (models) {
      EmailRegistration.hasMany(models.ContactDetails);
    };
    
    ContactDetails.associate = function(models) {
      ContactDetails.belongsTo(models.EmailRegistration, {
        onDelete: 'CASCADE',
        hooks: true,
        foreignKey: {
          name: 'emailregistrationid'
          allowNull: false
        },
      });
    }
    
    ContactDetails.create({
      ...
      emailregistrationid: <some_valid_emailregistrationid>
    })
    

    【讨论】:

    • 感谢您的回答。我确实更改了代码以按照您给出的方式实现它。但上述代码未能在 ContactDetails 表中添加列“emailregistrationid”。它只是创建模型文件中提到的列。其中没有对 emailregistrationid 的引用。请让我知道还有什么需要更改的。
    • 你在使用迁移吗?
    • 目前我没有使用,因为我刚刚开始迁移项目并被这个问题所困扰。
    • 它未能将 EmailRegistration 表的引用放入 ContactDetails 表中,无论代码更改为什么。不太明白,怎么回事?
    • 非常感谢您的解决方案。经过大量调试后,我发现,我缺少 Object.keys(db).forEach(modelName => { if (db[modelName].associate) { db[modelName].associate(db); } });加入我的 index.js 文件。添加后,连同您建议的解决方案,它起作用了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    相关资源
    最近更新 更多