【问题标题】:How to update different json (jsonb) attributes asynchronously with rails and postgres?如何使用rails和postgres异步更新不同的json(jsonb)属性?
【发布时间】:2019-08-13 18:13:33
【问题描述】:

我有一个大型 json 对象存储在 postgres 表列中,架构示例如下:

create_table “document” do |t|
    t.jsonb “data”, default: []
end

目前我正在更新列中的 json,如下所示:

# find document in rails then…
doucment.data[‘some_attribute’][2][‘another_attribute’] = 100
doucment.save

但是我多次写入这个 json 属性,有时数据会丢失,因为如果两个调用同时写入它,那么整个对象将被保存或用当前对象的旧数据覆盖。

例如,如果有两个不同的保存同时进行以下操作

保存 1:

doucment.data[‘some_attribute’][2][‘another_attribute’] = 100
doucment.save

保存 2:

doucment.data[‘some_attribute’][2][‘different_attribute’] = 200
doucment.save

那么任何一个属性数据都将丢失,因为另一个将保存它的 json 但带有尚未刷新的旧数据。

让这两个调用正确保存新数据的最佳方法是什么。

是否有任何 json 方法可以只进入并更新一个属性,例如 update_attribute 但对于 jsonb 属性?

【问题讨论】:

  • 你用的是什么版本的rails?
  • 我的回答有用吗?
  • @ErvalhouS 这是轨道 5.2.3

标签: ruby-on-rails json postgresql jsonb


【解决方案1】:

Postgresql 有jsonb_set 方法。您可以使用此方法更新您的模型。

使用此代码,记录在单个查询中更新:

Document.where(id: document.id).update_all(
  "data = jsonb_set(data, '{some_attribute,2,another_attribute}', to_json(#{your_int_value}::int)::jsonb)"
)

Related postgresql document

Answer that helps me

【讨论】:

  • 不幸的是,这不起作用,它表示名称为 int_value 的列不存在。
  • 最后效果很好,有一些更新,谢谢。
【解决方案2】:

这是因为您异步更新document,它与属性是json无关。

正确的做法是在修改模型之前锁定模型,这样它就不会被覆盖,而是一次更新一个步骤。

尝试以下方法:

Document.lock.find_by(...)

ActiveRecord::Locking::Pessimistic

【讨论】:

    猜你喜欢
    • 2019-03-04
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多