5

我有一列car_details包含 2000 个条目,每个条目都是一个信息哈希,如下所示:

{"capacity"=>"0",
 "wheels"=>"6",
 "weight"=>"3000",
 "engine_type"=>"Diesel",
 "horsepower"=>"350",
 "fuel_capacity"=>"35",
 "fuel_consumption"=>"30"}

有些汽车有更多的细节,有些则更少。我想将"fuel_consumption"钥匙重命名为"mpg"每辆拥有该钥匙的汽车。

4

3 回答 3

2

好吧,之前的答案会产生 2000 个请求,但您可以改用该REPLACE函数。MySQL 和 PostgreSQL 都有这个,所以它会像:

Car.update_all("car_details = REPLACE(car_details, 'fuel_consumption', 'mpg')")

看看update_all条件的方法。

另请参阅PostgreSQL 字符串函数MySQL 字符串函数

于 2013-10-22T21:35:00.250 回答
2

@Ivan Shamatov 发布的答案效果很好,对于在大型数据库上具有良好的性能尤为重要。

我在 jsonb 列上使用 PostgreSQL 数据库进行了尝试。 为了让它工作,我们必须同样注意数据类型转换。

例如在这样的User模型上:

User < ActiveRecord::Base {
                   :id => :integer,
           :created_at => :datetime,
           :updated_at => :datetime,
                :email => :string,
           :first_name => :string,
            :last_name => :string,
          :custom_data => :jsonb
}

custom_data我的目标是在jsonb 字段中重命名一个键。例如custom_data哈希内容来自:

{
                "foo" => "bar",
           "date" => "1980-07-10"
}

至:

{
                "new_foo" => "bar",
             "date" => "1980-07-10"
}

对于我的数据库中存在的所有用户记录。

我们可以执行这个查询:

old_key = 'foo'
new_key = 'new_foo'    
User.update_all("custom_data = REPLACE(custom_data::text, '#{old_key}'::text, '#{new_key}'::text)::jsonb")

这只会替换我们 jsonb 散列中的目标键(old_key),而不会更改散列值或其他散列键。

注意::text::jsonb类型转换!

于 2020-04-03T15:15:36.967 回答
1

据我所知,没有简单的方法可以使用原始 SQL 更新数据表中的序列化列。我能想到的最好方法是执行以下操作:

Car.find_each do |car|
  mpg = car.car_details.delete("fuel_consumption")
  car.car_details["mpg"] = mpg if mpg
  car.save
end

这是假设您正在使用 Active Record 并且您的模型称为“汽车”。

于 2013-10-22T21:28:38.670 回答