Bey*_*Sea 7 typescript typeorm
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;
}
Run Code Online (Sandbox Code Playgroud)
就像是 :
let contraption = await thingRepository.upsert({ name : "Contraption" });
Run Code Online (Sandbox Code Playgroud)
Ded*_*Dev 27
现在你可以使用upsert方法,
await this.yourRepository.upsert({name: 'John'}, ['id']) // assuming id is unique
Run Code Online (Sandbox Code Playgroud)
Unique首先用装饰器定义约束
@Entity()
@Unique('constraint_name', ['col_one', 'col_two'])
Run Code Online (Sandbox Code Playgroud)
然后在代码中就可以使用upsert方法了。
await this.yourRepository.upsert({name: 'John'}, ['constraint_name'])
Run Code Online (Sandbox Code Playgroud)
Bey*_*Sea 17
正如Tomer Amir所指出的,目前有一个部分真正upsert解决方案,一个功能请求是在TypeORM的存储库上打开ATM:
部分解决方案:
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();
Run Code Online (Sandbox Code Playgroud)
老答案实际上指的是做出OP要求的"更新"方式:
已经有了一种方法:Repository<T>.save()其文档说:
保存数据库中的所有给定实体.如果数据库中不存在实体,则插入,否则更新.
但是,如果未指定id或唯一字段集,则save方法无法知道您正在引用现有数据库对象.
因此,使用typeORM进行插入是:
let contraption = await thingRepository.save({id: 1, name : "New Contraption Name !"});
Run Code Online (Sandbox Code Playgroud)
Don*_*ong 16
对于在 2021 年发现此问题的任何人,Typeorm 的Repository.save()方法将在找到与主键匹配的情况下进行更新或插入。这也适用于 sqlite。
从文档:
/**
* Saves all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/
Run Code Online (Sandbox Code Playgroud)
小智 10
对于任何正在寻找插入多条记录的方法并正在使用 Postgres 和 TypeORM 的人,您都可以通过 exclude 关键字访问您尝试更新/插入的行。
const posts = [{ id: 1, title: "First Post" }, { id: 2, title: "Second Post" }];
await connection.createQueryBuilder()
.insert()
.into(Post)
.values(posts)
.onConflict(`("id") DO UPDATE SET "title" = excluded."title"`)
.execute();
Run Code Online (Sandbox Code Playgroud)
m.m*_*sni 10
这对我有用。
我结合了@DedaDev的答案。
您的实体
@Entity()
@Unique('constraint_name', ['id'])
Run Code Online (Sandbox Code Playgroud)
您的服务
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
},
);
Run Code Online (Sandbox Code Playgroud)
当ONCONFLICT不适用于 MySQL时,这可能会有所帮助。来自Github
await getConnection()
.createQueryBuilder()
.insert()
.into(GroupEntity)
.values(updatedGroups)
.orUpdate({ conflict_target: ['id'], overwrite: ['name', 'parentId', 'web', 'avatar', 'description'] })
.execute();
Run Code Online (Sandbox Code Playgroud)
使用INSERT IGNORE忽略 MySQL 和 Postgres 上的重复项:
await connection.createQueryBuilder()
.insert()
.into(Post)
.values(post)
.orIgnore()
.execute();
Run Code Online (Sandbox Code Playgroud)
2021 答案:v0.2.40 添加了对 TypeORM 的原生 upsert 支持
| 归档时间: |
|
| 查看次数: |
13215 次 |
| 最近记录: |