如何使用 sequelize 在一个数据库请求中将数据插入多个表?

Posted

技术标签:

【中文标题】如何使用 sequelize 在一个数据库请求中将数据插入多个表?【英文标题】:How to insert data to multiple tables in one db request with sequelize? 【发布时间】:2020-08-20 15:28:21 【问题描述】:

我有以下关系:

关联是:

  users.belongsToMany("roles", 
    through: "userRoles",
  );

创建用户时,我这样做:

register: async (obj, args, context, info) => 
  const PasswordHash = await bcrypt.hash(args.input.Password, 12);

  const user = db.users.create(
    ...args.input,
    Password: PasswordHash,
  );

  db.userroles.create(
    UserId: user.Id,
    RoleId: args.input.roleId,
  );
,

如何在一个请求中做到这一点?现在我在创建用户时做一个然后 获取新创建用户的 ID 并向该用户添加角色(请求 2)。

后续,假设我将有多个连接表绑定到用户表,我将如何再次 在一个数据库请求中插入所有表?

【问题讨论】:

什么是后备数据库?您需要通过 Sequelize 创建一个存储过程和收入。 我正在使用 mysql。你能举个例子吗? 我可以,您的用户 ID 是由数据库自动生成的吗? FWIW 最后的评论有一个错字“收入”应该是“电话”...... 【参考方案1】:

在您的 MySQL 数据库中创建一个存储过程以创建两条记录,例如

drop procedure if exists createUser
DELIMITER //
CREATE PROCEDURE createUser
(
    IN email VARCHAR(200),
    IN password BINARY(60),
    IN roleId INT
)
BEGIN
    DECLARE userId BINARY(16);

    INSERT INTO Users (Email, Password)
    VALUES (email, password);   

    # Assuming your user ID is auto-generated, pull ID of last insert
    SET userId = LAST_INSERT_ID()

    INSERT INTO UserRoles (UserId, RoleId)
    VALUES (userId, roleId);

END //

DELIMITER ;

然后您可以使用 Sequelize 调用该存储过程

const  email, roleId  = args.input;
const result = await sequelize
  .query('CALL createUser (:email, :password, :roleId)', 
        replacements:  email, password: PasswordHash, roleId );

您可以根据相关参数进行调整以适应,但您明白了。

【讨论】:

【参考方案2】:

除非您想在 MySQL 中创建自定义存储过程,否则无法同时创建用户和添加角色。

让我们尝试简化您的问题。在创建用户之前,您不知道 USER ID。因此,在创建用户之前不可能创建角色。解决此问题的一种方法是在您的代码中生成用户 ID。

您可以在“用户”表中添加一个名为 GeneratedId 的额外列,并将 ID 列转换为 AUTO_INCREMENT,然后在插入用户之前使用 https://www.npmjs.com/package/uuid 等包生成唯一 ID。

使用生成的相同Id将角色与用户关联(“UserRole”表中的“UserId”列将包含您在代码中生成的Id)。

现在您可以添加用户和所有相关数据,而无需等待服务器的答复。

【讨论】:

以上是关于如何使用 sequelize 在一个数据库请求中将数据插入多个表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在sequelize中将外键引用到另一个外键?

在 Sequelize 迁移中将 defaultValue 设置为今天的日期

如何使用 TypeScript 正确键入 Sequelize JOIN?

在 Sequelize 中将模型的条件与其关联的条件结合起来

如何在 sequelize 查询中使用查询参数作为列名

在mysql Sequelize + Nodejs中将数组和对象转换为批量插入