我想批量处理 insert
或 update
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
有更好的方法,欢迎提出建议。
答案 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"}]
希望这至少可以为您提供临时修复。