我使用Ruby和Datamapper将大量记录加载到MySQL数据库中。这些记录主要是插入,但有相当多的更新。我基本上想要'upsert'数据库中这些记录的所有列。我能找到的唯一选择是:
1)查询记录。如果存在,请更新它。如果没有,请创建一条记录。 (总是一个额外的查询) 2)尝试创建新记录。捕获重复的键错误。查询现有记录。更新这些记录。 (当有更新时,2个额外查询)
我想利用MySQL的On Duplicate Key Update
,因为它看起来效率更高。有没有办法在Datamapper中执行此操作?还有其他建议吗?
答案 0 :(得分:0)
您应该可以使用first_or_create
。来自docs:
zoo = Zoo.first_or_create(:name => 'The Glue Factory')
我没有通过在do/do_mysql
或dm-mysql-adapter
来源中点击On Duplicate Key Update
来获得任何匹配,因此它可能不支持它。如果要求此功能的效率非常重要,则可能需要使用纯SQL。
答案 1 :(得分:0)
这不是开箱即用的受支持功能,但如果您正在进行批量插入,请在事务中执行此操作,即使使用额外查询也会更有效。并使用first_or_new
,这样就不会对新记录进行多次插入。
DataMapper.respository.transaction.commit do
Zoo.raise_on_save_failure = true
bunch_of_updates.each do |key, new_attributes|
zoo = Zoo.first_or_new(the_key: key)
zoo.attributes = new_attributes
zoo.save
end
end