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列的值相等时,两行被视为重复。