findOrCreate 包含 - Sequelize.js

问题描述 投票:0回答:2

我想创建一个锦标赛(如果不存在),以及与锦标赛关联的比赛(如果不存在)。

let [match, created] = await Match.findOrCreate( {
  where: {scoreHome: 97, Tournament: {name: "USA South Men's Basketball"}}, 
  include: [Tournament]
})

如果锦标赛“USA South Men's篮球”已在数据库中(假设 ID 为 1),则应使用 TournamentId: 1 创建比赛。如果数据库中已存在带有

{scoreHome: 97 and TournamentId: 1}
的比赛,则不会应该创建匹配。

  let Match = sequelize.define('Match', {
    scoreHome: DataTypes.INTEGER,
    //...
  })

  Match.associate = models => {
    Match.belongsTo(models.Tournament)
  }

编辑 错误如下:

[错误:无效值 [对象对象]]

这个效果很好

let match = await Match.create({
    scoreHome: 97, Tournament: {name: "USA South Men's Basketball"}
  },{include: [Tournament]}
})
javascript sequelize.js
2个回答
1
投票

我不确定续集是否允许这种“深度查找或创建”。 但是您可以使用两个查询和续集事务来实现所需的效果,以确保两者链接在一起:

const t = await sequelize.transaction();

try {
  const [tournament] = await Tournament.findOrCreate({
    where: {name: "USA South Men's Basketball"},
    { transaction: t }
  })
  const [match] = await Match.findOrCreate({
    where: {scoreHome: 97, tournamentId: tournament.id},
    { transaction: t }
  })
  t.commit()
} catch(err) {
  t.rollback()
}

它有点冗长,但是这样你就可以确定自己在做什么,并且(个人观点)对于在你之后阅读该内容的其他开发人员来说也更具可读性。


0
投票

您遇到的问题是因为

findOrCreate
不直接处理嵌套关系,就像
create
处理包含一样。你可以试试这个:

// First, find or create the Tournament
let [tournament] = await Tournament.findOrCreate({
  where: { name: "USA South Men's Basketball" }
});

// Now, find or create the Match using the Tournament's ID
let [match, created] = await Match.findOrCreate({
  where: { scoreHome: 97, TournamentId: tournament.id }
});
© www.soinside.com 2019 - 2024. All rights reserved.