Upsert 数据
upsert()用于对表(table)或视图(view)执行 UPSERT 操作。
在关系型数据库中,Upsert是一种结合了"插入(Insert)“和"更新(Update)“的操作,它允许我们在表或视图上执行插入或更新操作。
通常情况下,当我们想要向数据库中插入一行数据时,我们会使用INSERT语句。
但是,如果该行数据已经存在(通常通过主键来判断),我们可能希望更新该行数据而不是插入重复的数据。
Upsert通过传递列到onConflict
方法,我们可以使用.upsert()
来实现以下功能:
如果不存在具有相应onConflict
列的行,则执行等效于.insert()
的插入操作。
如果存在具有相应onConflict
列的行,则根据ignoreDuplicates
的设置执行另一种操作。
需要注意的是,为了使用upsert,必须在values
中包含主键。主键是用于唯一标识表中每一行的一列或一组列,确保数据的唯一性和完整性。
案例1 (Upsert数据) link
create table
countries (id int8 primary key, name text);
insert into
countries (id, name)
values
(1, 'Afghanistan');
const { data, error } = await supabase
.from('countries')
.upsert({ id: 1, name: 'Albania' })
.select()
{
"data": [
{
"id": 1,
"name": "Albania"
}
],
"status": 201,
"statusText": "Created"
}
案例2 (批量Upsert数据) link
create table
countries (id int8 primary key, name text);
insert into
countries (id, name)
values
(1, 'Afghanistan');
const { data, error } = await supabase
.from('countries')
.upsert([
{ id: 1, name: 'Albania' },
{ id: 2, name: 'Algeria' },
])
.select()
{
"data": [
{
"id": 1,
"name": "Albania"
},
{
"id": 2,
"name": "Algeria"
}
],
"status": 201,
"statusText": "Created"
}
案例3 (将数据Upsert到带有约束的表中) link
create table
users (
id int8 generated by default as identity primary key,
handle text not null unique,
display_name text
);
insert into
users (id, handle, display_name)
values
(1, 'saoirse', null);
const { data, error } = await supabase
.from('users')
.upsert({ id: 42, handle: 'saoirse', display_name: 'Saoirse' }, { onConflict: 'handle' })
.select()
{
"error": {
"code": "23505",
"details": "Key (handle)=(saoirse) already exists.",
"hint": null,
"message": "duplicate key value violates unique constraint \"users_handle_key\""
},
"status": 409,
"statusText": "Conflict"
}
在以下查询中,upsert()
隐式地使用 id
(主键)列来确定冲突。如果没有现有的行具有相同的 id
,
upsert()
将插入一行新数据,但在这种情况下会失败,因为已经存在一个具有 handle
为 saoirse
的行。
通过使用 onConflict
选项,您可以指示 upsert()
使用另一个带有唯一约束的列来确定冲突。
值(value)
[必要参数]
object类型
要用的值来upsert。传递一个对象来替换单行单一行,或者通过一个数组来插入多行。
选项(option)
[可选参数]
object类型
特性
count
[可选参数]
exact
| planned
| estimated
用来计算更新行的计数算法。
exact:可以精确计算行数,但执行速度较慢。执行 COUNT(*) 操作。
planned:可以快速计算行数,但是结果可能略有偏差。使用了Postgres
的统计数据。
estimated:对于较小的数值使用精确计数,对于较大的数值使用计划计数。根据行数的大小决定使用精确计数或计划计数的算法。
defaultToNull
[可选参数]
boolean类型
ignoreDuplicates
[可选参数]
boolean类型
用来计算更新行的计数算法。
如果为true,则忽略重复的行。如果为false,则将重复的行与现有行合并。
onConflict
[可选参数]
string类型
用来计算更新行的计数算法。
逗号分隔的UNIQUE列,用于指定如何确定重复行。当所有onConflict列的值相等时,两行被视为重复。