有没有办法使用 Sequelize 一次将多个嵌入式模型保存在数据库中

Posted

技术标签:

【中文标题】有没有办法使用 Sequelize 一次将多个嵌入式模型保存在数据库中【英文标题】:Is there a way to save multiple embedded models in db at once using Sequelize 【发布时间】:2017-04-13 11:03:51 【问题描述】:

假设我们在 NodeJs 中有这样的结构 Sequelize。

var User = sequelize.define('user', /* ... */)
var Project = sequelize.define('project', /* ... */)

Project.hasMany(User)

在this part of video 中,presenter 提出使用 Promise 通过两个步骤保存嵌入对象。在我们的例子中,它会是这样的:

Project.create(
  ...
  ).then(function(project)
     User.create(
        ...
        projectId:project.id
     )
   )

但这种方法会导致 两次 db 调用。

那么,是否可以通过一次 db 调用或在使用 Sequelize 的事务中将嵌入对象(包含用户的项目,例如用户必须将项目的 id 作为外键)保存到数据库中?

【问题讨论】:

【参考方案1】:

您应该能够通过将对象数组传递到与"as" 上使用的"as" 值同名的键来插入父子对象@。虽然documentation is light上的用法,你可以看到它在source code here中处理。

没有承诺(双关语半有意)这是实际上在单个 SQL 查询中运行,不确定 Sequelize 中的确切实现。您应该能够启用日志记录(Sequelize(options) 中的logging: console.log)以查看它正在运行什么。

// specify an "as" value and require a User.project_id value
Project.hasMany(User,  as: 'Users', foreignKey:  allowNull: false  );

// define your Project -> Users as json with the "as" value as the key
const project = 
  name: 'project name',
  Users: [
    
      name: 'user 1',
    ,
    
      name: 'user 2',
    ,
  ],
;

// create a transaction and "include" the Model in the create, txn falls back in .catch()
sequelize.transaction(t => 
  Project.create(project, 
    include: [
      model: User,
      as: 'Users',
    ],
    transaction: t,
  )
)
.catch(e => console.log('the txn failed because', e));

【讨论】:

感谢您的回复)。它按预期保存所有数据,但日志显示多个“正在执行”行具有相同的键:Executing (some_key): START TRANSACTION; Executing (the_same_key): SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; Executing (the_same-Key): INSERT INTO "user" ... RETURNING *; Executing (the_same-Key): ...other inserts... Executing (the_same-Key): COMMIT; Dose 相同的键显示所有事情都发生在一个查询中? 我对此表示怀疑,这通常是使用 ORM 权衡的一部分。 并且澄清一下,如果任何 INSERTS 失败,通过将其包装在事务中,它们都将被回滚。也有可能一次将多个查询发送到服务器而不是来回发送,但在性能方面我认为可以忽略不计。 好的,明白了。由于我的声誉,我无法支持您的答案,但我会将其标记为已回答。

以上是关于有没有办法使用 Sequelize 一次将多个嵌入式模型保存在数据库中的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Swift 中一次将委托分配给同一类的多个对象?

一次将多个图像上传到 Firebase

如何一次将多个 csv 文件读取到 Google Colab

Sequelize:批量插入

一次将 pandas 数据帧随机分组以进行 x 折交叉验证

使用 Summernote File 一次将多个文件上传到服务器