简体   繁体   English

Sequelize - 多对多关联 - 3 个外键

[英]Sequelize - Association Many to Many - 3 Foreign Keys

I'm looking for some help on properly defining an association table with 3 foreign keys in a Sequelize model:我正在寻找有关在 Sequelize 模型中正确定义具有 3 个外键的关联表的一些帮助:

Situation: I'm building an email client, the relative models to this question are:情况:我正在构建一个电子邮件客户端,这个问题的相关模型是:

  • User Model (user records)用户模型(用户记录)
  • Thread Model (thread records for each new email-thread)线程模型(每个新电子邮件线程的线程记录)
  • Folder Model (folders for default folders eg inbox, sent, etc and custom folders)文件夹模型(默认文件夹的文件夹,例如收件箱、已发送等和自定义文件夹)
  • ThreadFolder Model (association linking a specific a) User Model, to a specific b) Thread Model, to a specific c) Folder Model) ThreadFolder模型(将特定 a)用户模型链接到特定 b)线程模型,到特定 c)文件夹模型的关联

Problem: My problem is the association model/table (ThreadFolder), I'm not able to create an association for all 3 tables in the ThreadFolder association Model.问题:我的问题是关联模型/表 (ThreadFolder),我无法为 ThreadFolder 关联模型中的所有 3 个表创建关联。


First Attempt I'm able to create an association with Sequelize that allows the ThreadFolder model to create foreign keys for 2 of the three models above, but not all 3. Here is the association for that:第一次尝试我能够创建与 Sequelize 的关联,允许 ThreadFolder 模型为上述三个模型中的两个创建外键,但不是全部 3 个。这是关联:

Thread.belongsToMany(Folder, { through: ThreadFolder, foreignKey: 'thread_id', otherKey: 'folder_id' })
Folder.belongsToMany(Thread, { through: ThreadFolder, foreignKey: 'folder_id', otherKey: 'thread_id' })

SQL Input Attempts: SQL 输入尝试:

  1. user_id: 1 |用户 ID:1 | thread_id: 1 | thread_id: 1 | folder_id: 1 | folder_id: 1 | Successful Insert成功插入
  2. user_id: 1 |用户 ID:1 | thread_id: 1 | thread_id: 1 | folder_id: 2 | folder_id: 2 | Successful Insert成功插入
  3. user_id: 1 |用户 ID:1 | thread_id: 2 | thread_id: 2 | folder_id: 1 | folder_id: 1 | Failed Insert -- Error below...插入失败 -- 以下错误...
  4. user_id: 2 |用户 ID:2 | thread_id: 1 | thread_id: 1 | folder_id: 1 | folder_id: 1 | Successful Insert成功插入
  5. user_id: 2 |用户 ID:2 | thread_id: 1 | thread_id: 1 | folder_id: 2 | folder_id: 2 | Successful Insert成功插入

First Attempt's Error:第一次尝试的错误:

Executing:
INSERT INTO `iwantmail-core`.`thread_folders` (`user_id`, `deleted`, `archived`, `created_at`, `updated_at`, `thread_id`, `folder_id`) VALUES ('1', '0', '0', '2020-03-05 23:34:16', '2020-03-05 23:34:16', '30', '1');

Operation failed: There was an error while applying the SQL script to the database.
ERROR 1062: 1062: Duplicate entry '30-1' for key 'PRIMARY'
SQL Statement:
INSERT INTO `iwantmail-core`.`thread_folders` (`user_id`, `deleted`, `archived`, `created_at`, `updated_at`, `thread_id`, `folder_id`) VALUES ('1', '0', '0', '2020-03-05 23:34:16', '2020-03-05 23:34:16', '30', '1')

Second Attempt I can specify the association as shown below, to allow me to add records with different user_id and folder_id, however, if I use a different thread_id, I get an error shown below.第二次尝试我可以指定如下所示的关联,以允许我添加具有不同 user_id 和 folder_id 的记录,但是,如果我使用不同的 thread_id,我会收到如下所示的错误。

Folder.hasMany(ThreadFolder, { foreignKey: 'folder_id' })
ThreadFolder.belongsTo(Folder, { foreignKey: 'folder_id' })
Thread.belongsToMany(Folder, { through: ThreadFolder })

Thread.hasMany(ThreadFolder, { foreignKey: 'thread_id' })
ThreadFolder.belongsTo(Thread, { foreignKey: 'thread_id' })

User.hasMany(ThreadFolder, { foreignKey: 'user_id' })
ThreadFolder.belongsTo(User, { foreignKey: 'user_id' })
Folder.belongsToMany(User, { through: ThreadFolder })

SQL Input Attempts: SQL 输入尝试:

  1. user_id: 1 |用户 ID:1 | thread_id: 1 | thread_id: 1 | folder_id: 1 | folder_id: 1 | Successful Insert成功插入
  2. user_id: 1 |用户 ID:1 | thread_id: 1 | thread_id: 1 | folder_id: 2 | folder_id: 2 | Successful Insert成功插入
  3. user_id: 1 |用户 ID:1 | thread_id: 2 | thread_id: 2 | folder_id: 1 | folder_id: 1 | Failed Insert -- Error below...插入失败 -- 以下错误...
  4. user_id: 2 |用户 ID:2 | thread_id: 1 | thread_id: 1 | folder_id: 1 | folder_id: 1 | Successful Insert成功插入
  5. user_id: 2 |用户 ID:2 | thread_id: 1 | thread_id: 1 | folder_id: 2 | folder_id: 2 | Successful Insert成功插入

Second Attempt's Error第二次尝试的错误

Operation failed: There was an error while applying the SQL script to the database.
ERROR 1062: 1062: Duplicate entry '1-1' for key 'PRIMARY'
SQL Statement:
INSERT INTO `mail-core`.`thread_folders` (`user_id`, `thread_id`, `folder_id`) VALUES ('1', '2', '1')

Note that I'm basically trying to indicate that User#1 of Thread#1 are in Folder#1 and as soon as I try to indicate that User#1 of Thread#2 are in Folder#1, the above error occurs.请注意,我基本上是想指出 Thread#1 的 User#1 位于 Folder#1 中,一旦我尝试指出 Thread#2 的 User#1 位于 Folder#1 中,就会发生上述错误。


Help:帮助:

  • Could someone please point me towards the right direction / show how the association should be written to take into account the 3rd association?有人可以指出我正确的方向/展示应该如何编写关联以考虑到第三个关联吗?
  • Is there a different way to write this association all together so all 3 foreign keys are taken into account in the association table?有没有一种不同的方式来编写这个关联,以便在关联表中考虑所有 3 个外键?

Thanks for any help/assistance in advance!提前感谢您的任何帮助/协助!

(Relative technologies used: MySQL, MySQL Workbench, Node 12.x, TypeScript, Serverless Framework) (使用的相关技术:MySQL、MySQL Workbench、Node 12.x、TypeScript、Serverless Framework)

EDIT: Made edits to the post, 2nd attempt was presented as a partial solution, after further testing, both 1st and second attempts fail when a 2nd user is added to the same thread and folder in the association table ThreadFolder.编辑:对帖子进行了编辑,第二次尝试作为部分解决方案提出,经过进一步测试,当第二个用户添加到关联表 ThreadFolder 中的同一线程和文件夹时,第一次和第二次尝试均失败。

After looking at your create statements I think you have defined associations thread_folders properly.查看您的创建语句后,我认为您已经正确定义了关联thread_folders In my opinion, your second attempt at defining association is correct.在我看来,您第二次尝试定义关联是正确的。

You are getting an error while inserting records because your primary key is the combined key of two attributes namely thread_id and folder_id .插入记录时出现错误,因为您的主键是两个属性的组合键,即thread_idfolder_id Let us say that in your thread_folders table there is already record for thread_id 1 and folder_id 1 then you can not insert another record with thread_id 1 and folder_id 1.假设在您的thread_folders表中已经有thread_id 1 和folder_id 1 的记录,那么您不能插入另一个具有thread_id 1 和folder_id 1 的记录。

If you remove the combined primary key of thread_id and folder_id then you will be able to insert the records that you want to insert in the thread_folders table.如果您删除thread_idfolder_id的组合主键,那么您将能够在thread_folders表中插入要插入的记录。

I hope it helps!我希望它有帮助!

Working solution ended up being a variance of the second attempt:工作解决方案最终成为第二次尝试的差异:

User.hasMany(ThreadFolder, { foreignKey: 'user_id' })
ThreadFolder.belongsTo(User, { foreignKey: 'user_id' })

Folder.hasMany(ThreadFolder, { foreignKey: 'folder_id' })
ThreadFolder.belongsTo(Folder, { foreignKey: 'folder_id' })

Thread.hasMany(ThreadFolder, { foreignKey: 'thread_id' })
ThreadFolder.belongsTo(Thread, { foreignKey: 'thread_id' })

Most of my model calls (based on how they were written before) will end up changing to start with the association table first eg我的大部分模型调用(基于它们之前的编写方式)最终都会更改为首先从关联表开始,例如

 ThreadFolder.findAll({
        where: {
            user_id: 1,
            folder_id: 1,
        },
        include: [
            {
                model: Thread,
                include: [
                    'recipient',
                    'sender'
                ]
            }
        ]
    })

Hope this helps others that have attempted to do a multi-foreign key association table beyond 2 foreign keys, presumable this approach should work with any amount of foreign keys in the association table.希望这有助于其他试图做超过 2 个外键的多外键关联表的人,假设这种方法应该适用于关联表中的任意数量的外键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM