TypeORM:在没有 id 的情况下更新冲突

时间:2021-02-28 11:45:25

标签: mysql sql node.js typeorm

我想批量处理 insertupdate if exists 表中的行,而无需事先了解该行的 id(如果存在)。我正在使用 TypeORM。在这种情况下,我想要 update 行,其中 uniqueKey 存在并带有新的 title,而 insert 不存在。

const data = [
  {title: 'New Title', user: 123, uniqueKey: 'abc'},
  {title: 'Another New Title', user: 123, uniqueKey: 'xyz' }
 ]

await repo
    .createQueryBuilder()
    .insert()
    .into(Posts)
    .values(data)
    .orUpdate({ conflict_target: ['uniqueKey'], overwrite: ['title']  })
    .execute();

以上抛出错误:

Error: Cannot update entity because entity id is not set in the entity.

如果对批量 upsert 有更好的方法,欢迎提出建议。

2 个答案:

答案 0 :(得分:0)

就我而言,最好的方法是始终不要隐藏 SQL 数据库。

使用透明函数构建查询甚至可能会阻止您使用纯 SQL 执行我在此处执行的操作(我不了解 node.js,但其他 SQL 包装器用这个让我窒息...)

>

哦,还有 user 是保留字;它包含当前连接到 MySQL 的用户名..

INSERT INTO posts (title,userid,unique_key)
VALUES ('New Title'        , 123, 'abc')
ON DUPLICATE KEY UPDATE title='New Title';

INSERT INTO posts (title,userid,unique_key)
VALUES ('Another New Title', 123, 'xyz')
ON DUPLICATE KEY UPDATE title='Another New Title';

或者,对于批量插入,填充一个临时表,结构与posts相同,然后:

INSERT INTO posts (title,userid,unique_key)
SELECT
  title
, userid
, unique_key
FROM posts_tmp t
ON DUPLICATE KEY UPDATE title = t.title, userid=t.userid;

答案 1 :(得分:0)

我在尝试批量 .orUpdate 没有“id”字段的对象数组时遇到了这个确切的问题。我所要做的就是为我导入的每个对象添加 id 字段,因为我相信它用于在执行 .orUpdate 时迭代每个对象的“元数据”。

我也使用 MySQL,这里是我的例子中的代码(url 是 uniqueKey):

 const result = await connection
    .createQueryBuilder()
    .insert()
    .into(Channel)
    .values(data)
    .orUpdate({
      conflict_target: ["url"],
      overwrite: ["name", "imgurl", "subscribers"],
    }) //If channel exists we update its info.
    .execute()
    .catch((err) => err);

当我的对象具有这种结构时,我会遇到您提到的相同错误:

data = [{name : "name", imgurl : "imgurl", url: "url1"}, { name : "name", imgurl : "imgurl", url: "url2"}]

遍历对象数组并向每个对象添加增量 id 解决了问题:

data = [{id: 1, name : "name", imgurl : "imgurl", url: "url1"}, {id: 2, name : "name", imgurl : "imgurl", url: "url2"}]

希望这至少可以为您提供临时修复。