TypeORM upsert - 如果不存在则创建

新手上路,请多包涵

TypeORM 是否包含一些功能来避免这种情况:

 let contraption = await thingRepository.findOne({ name : "Contraption" });

if(!contraption) // Create if not exist
{
    let newThing = new Thing();
    newThing.name = "Contraption"
    await thingRepository.save(newThing);
    contraption = newThing;
}

就像是 :

 let contraption = await thingRepository.upsert({ name : "Contraption" });

原文由 LucasBordeau 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.6k
2 个回答

正如 Tomer Amir 所指出的,目前有一个针对 真正 upsert 的部分解决方案,并且功能请求是在 TypeORM 的存储库上打开的 ATM :

TypeORM upsert 功能请求

部分解决方案:

 await connection.createQueryBuilder()
        .insert()
        .into(Post)
        .values(post2)
        .onConflict(`("id") DO NOTHING`)
        .execute();

await connection.createQueryBuilder()
        .insert()
        .into(Post)
        .values(post2)
        .onConflict(`("id") DO UPDATE SET "title" = :title`)
        .setParameter("title", post2.title)
        .execute();


旧答案实际上指向了执行 OP 要求的“更新”方式:

已经有一种方法: Repository<T>.save() ,其中文档说:

将所有给定的实体保存在数据库中。如果数据库中不存在实体,则插入,否则更新。

但是,如果您不指定 id 或唯一的字段集,则 save 方法无法知道您正在引用现有的数据库对象。

所以使用 typeORM 更新插入是:

 let contraption = await thingRepository.save({id: 1, name : "New Contraption Name !"});

原文由 LucasBordeau 发布,翻译遵循 CC BY-SA 4.0 许可协议

这对我有用。

我结合了 @DedaDev 的答案。

您的实体

@Entity()
@Unique('constraint_name', ['id'])

您的服务

await this.yourRepository.upsert(
  {
    id: uuid,
    key1: value1,
    ...
  },
  {
    skipUpdateIfNoValuesChanged: true, // If true, postgres will skip the update if no values would be changed (reduces writes)
    conflictPaths: ['id'], // column(s) name that you would like to ON CONFLICT
  },
);

原文由 user2417554 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Stack Overflow 翻译
子站问答
访问
宣传栏