如何为 Sequelize 模型设置外键?

Sha*_*oon 5 javascript postgresql node.js sequelize.js

这是非常基本的,应该可以工作..但不行。首先是我的模型:

const Conversation = sequelize.define('Conversation', {
        name: {
            type: DataTypes.STRING,
            allowNull: false
        },
        ...
})
Conversation.associate = (models, options) => {
    Conversation.hasOne(models.Audio, options)
}
Run Code Online (Sandbox Code Playgroud)

和:

module.exports = (sequelize /*: sequelize */ , DataTypes /*: DataTypes */ ) => {
    const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
    })

    Audio.associate = (models, options) => {
        Audio.belongsTo(models.Conversation, options)
    }
Run Code Online (Sandbox Code Playgroud)

我有一个模型加载器,它可以:

    fs.readdirSync(`${__dirname}`)
        .filter((modelFile) => {
            return path.extname(modelFile) === '.js' && modelFile !== 'index.js'
        })
        .map((modelFile) => {
            let model = sequelize.import(`./${modelFile}`)
            models[model.name] = model

            return model
        })
        .filter((model) => models[model.name].associate)
        .forEach((model) => {
            models[model.name].associate(models, {
                hooks: true,
                onDelete: 'CASCADE'
            });
        })
Run Code Online (Sandbox Code Playgroud)

因此它会调用associate定义了该方法的所有模型的方法。这是有效的,因为当我.sync这样做时,它会ConversationId在我的Conversations表中创建一个字段。

当我尝试执行时:

            let updAudio = {
                ConversationId,
                name: 'myname'
            }
            await global.db.models.Audio.create(updAudio, { logging: console.log })
Run Code Online (Sandbox Code Playgroud)

ConversationId不为空,但是当它保存到数据库中时,它是空的。我已经检查过一百次了。原始查询如下所示:

INSERT INTO "Audios" ("id","name","createdAt","updatedAt") VALUES (DEFAULT,'myname','2019-10-20 19:59:18.139 +00:00','2019-10-20 19:59:18.139 +00:00') RETURNING *;
Run Code Online (Sandbox Code Playgroud)

那么发生了什么ConversationId

Col*_*rus 9

您可能需要在模型定义中添加外键:

(两者之一可能有效)

 const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
        conversationId : {
            type: Sequelize.INTEGER,
            references: 'Conversations' // or "conversations"? This is a table name
            referencesKey: 'id' // the PK column name
        }
    })
Run Code Online (Sandbox Code Playgroud)

或者

 const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
        conversationId : {
            type: Sequelize.INTEGER,
            references: {
                model: Conversation
                key: 'id'
            }
        }
    })
Run Code Online (Sandbox Code Playgroud)

您可能还需要belongsTo这样定义您的关联:

Audio.belongsTo(Conversation, foreignKey: 'conversationId');
Run Code Online (Sandbox Code Playgroud)

尝试查找在创建表时生成的原始查询并从那里开始。

  • 如果您使用第三个,则无需编写前两个。因为第三个会自动添加外键字段 (4认同)