【问题标题】:Does Datamapper support 'On Duplicate Key Update' or other techniques for upserts?Datamapper 是否支持“On Duplicate Key Update”或其他用于 upserts 的技术?
【发布时间】:2012-08-19 10:12:03
【问题描述】:

我正在使用 Ruby 和 Datamapper 将大量记录加载到 MySQL 数据库中。这些记录主要是插入,但有相当数量的更新。我基本上想“更新”数据库中这些记录的所有列。我能找到的唯一选择是:

1) 查询记录。如果存在,请更新它。如果没有,请创建一个记录。 (总是一个额外的查询) 2) 尝试创建新记录。捕获重复的键错误。查询现有记录。更新这些记录。 (有更新时,2个额外查询)

我想使用 MySQL 的 On Duplicate Key Update,因为它看起来效率更高。有没有办法在 Datamapper 中做到这一点?还有其他建议吗?

【问题讨论】:

    标签: mysql ruby datamapper


    【解决方案1】:

    您应该可以为此使用first_or_create。来自docs:

    zoo = Zoo.first_or_create(:name => 'The Glue Factory')
    

    我没有通过在do/do_mysql 或dm-mysql-adapter 源中搜索On Duplicate Key Update 得到任何匹配,因此它可能不支持它。如果效率对于需要此功能非常重要,您可能需要求助于普通 SQL。

    【讨论】:

    • 是的,我也没有找到任何痕迹。我可能不得不为此使用mysql2。谢谢。
    【解决方案2】:

    这不是开箱即用的受支持功能,但如果您要进行批量插入,请在事务中进行,即使使用额外的查询也会更有效。并使用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
    

    【讨论】:

    • 酷。下次我会记住这个技巧的。不幸的是,我不能像那样查询我的更新。我正在处理 xml 记录,在运行插入之前有太多数据需要保存在内存中。看来我必须使用 mysql2(生产)和 sqlite3(测试)来“更新”。
    • 明白了。您可以直接从 DataMapper 中使用适配器来执行此操作,例如 DataMapper.repository.adapter.execute("some sql")。或者您可以将来自 datamapper 的查询保留在内存中并流式传输 xml,然后运行类似DataMapper.repository.adapter.create(query) 的查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    相关资源
    最近更新 更多