我刚开始在一个非常小的Sinatra应用程序中使用Sequel。由于我只有一个数据库表,所以我不需要使用模型。
我想更新记录(如果存在)或插入新记录(如果不存在)。我提出了以下解决方案:
rec = $nums.where(:number => n, :type => t)
if $nums.select(1).where(rec.exists)
rec.update(:counter => :counter + 1)
else
$nums.insert(:number => n, :counter => 1, :type => t)
end
$nums
是DB[:numbers]
数据集的位置。
我认为这种方式不是“更新或插入”行为的最优雅实现。
应该怎么做?
答案 0 :(得分:17)
在更新/插入之前,您可能不应该检查;这是因为:
您应该做的是测试更新的返回值:
rec = $nums.where(:number => n, :type => t)
if 1 != rec.update(:counter => :counter + 1)
$nums.insert(:number => n, :counter => 1, :type => t)
end
答案 1 :(得分:10)
续集4.25。0(2015年7月31日发布)增加了insert_conflict
for Postgres v9.5+
续集4.30.0(2016年1月4日发布)增加了insert_conflict
for SQLite
这可用于插入或更新行,如下所示:
DB[:table_name].insert_conflict(:update).insert( number:n, type:t, counter:c )
答案 2 :(得分:3)
我相信你不能比它更清洁(虽然有些数据库有特定的upsert语法,可能是supported by Sequel)。您可以在单独的方法中包装您拥有的内容并假装它不存在。 :)
只是几点建议:
(number, type)
字段上创建唯一索引。答案 3 :(得分:1)
您可以使用upsert,但目前无法更新计数器。希望未来的版本会 - 欢迎提出想法!