我正在尝试使用 activerecord-import 导入数据,但遇到了问题。如果该行已经存在,则需要更新它,否则需要创建它。表中的唯一行由两列的组合定义,其中每个列值在表中可能不是唯一的。由于列不是唯一列,我将如何使用 on_duplicate_key_update 的 conflict_target。
现在详细介绍。我有一个名为 Order 的模型,下面是 Order 模型中列的简化版本。
id
order_number
sku_number
quantity
数据库中的唯一行由 order_number 和 sku_number 的组合标识。 id 列自动递增。通常,如果我有一个唯一的列作为标识符,我可以执行如下操作。因此,在下面的示例中,假设 id 列是唯一标识符,我将使用 id 列作为 conflict_target。
order = Order.create(order_number: '1', sku_number: '1', quantity: 100)
order.quantity = 200
Order.import [order], on_duplicate_key_update: {conflict_target: [:id], columns: [:quantity]}
这会更新数量,因为订单已经存在。
但是我需要的是类似
Order.import [order], on_duplicate_key_update: {conflict_target: [:order_number, :sku_number], columns: [:quantity]}
其中 order_number 和 sku_number 将唯一标识冲突行。
但这失败了,因为 Postgres 期望 conflict_target 有一个唯一的列。
有没有什么方法可以使用非唯一列(即 order_number 和 sku_number)调用 on_duplicate_key_update?
如有任何帮助,我们将不胜感激。
最佳答案
我想通了。我正在记下解决方案,以防其他人遇到同样的问题。
我最终在 Order 上创建了一个唯一索引
class AddUniqueKeyConstraintToOrders < ActiveRecord::Migration
def change
add_index :orders, [:order_number, :sku_number], unique: true
end
end
activerecord-import 支持使用索引作为约束。所以我最终做了类似
的事情order = Order.last
order.quantity = 200
Order.import [order], on_duplicate_key_update: {conflict_target: [:order_number, :sku_number], index_name: :index_orders_on_order_number_and_sku_number, columns: [:quantity]}
其中 index_orders_on_order_number_and_sku_number 是迁移创建的索引的名称。它将数量从以前的值更新为 200,而没有创建额外的记录。
关于ruby-on-rails - 具有非唯一列的 Activerecord-import upsert 到 postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39996566/