sql语句将jsonbhash转换为json字符串

fykwrbwg  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(453)

我有一个rails数据迁移(postgresdb),由于一些模型限制,我必须使用纯sql来转换数据。数据以字符串的形式存储为json,但我需要它是一个可用于其他目的的哈希。
我的迁移工作是把它转换成散列。但是,我的down方法最终只是删除数据或将其保留为空{}。顺便说一句,为了消除任何混乱,我的列名实际上保存为 data 在表中 Games 基于我的up方法,如何仅使用sql正确地反转迁移?

class ConvertGamesDataToJson < ActiveRecord::Migration[6.0]
  def up
    statement = <<~SQL
      update games set data = regexp_replace(trim(both '"' from data::text), '\\\\"', '"', 'g')::jsonb;
    SQL

    ActiveRecord::Base.connection.execute(statement)
    # this part works!
  end

  def down
    statement = <<~SQL
      update games set data = to_json(data::text)::jsonb;
    SQL

    ActiveRecord::Base.connection.execute(statement)
  end
end

以下是正确转换后的it外观

data: {
  "id"=>"d092a-f2323",
  "recent"=>'yes',
  "note"=>"some text",
  "order"=>1
}

迁移前的状态以及回滚到的目标:

data: 
  "{
    \"id\":\"d092a-f2323\",
    \"recent\":\"yes\",
    \"note\":\"some text\",
    \"order\":1,
  }"
0x6upsns

0x6upsns1#

如果在rails控制台中显示数据结构 \" 其实并不存在。它们只是格式化,因为控制台已将字符串 Package 在 " . 例如。。。

[2] pry(main)> %{"up": "down"}
=> "\"up\": \"down\""

但如果我们把它打印出来。。。

[3] pry(main)> puts %{"up": "down"}
"up": "down"

假设这是一个json字符串,您只需将列的类型更改为jsonb,就可以使用它了。

-- up
alter table games alter column data type jsonb USING data::jsonb;

-- down
alter table games alter column data type text;

postgres不知道如何将文本自动转换为jsonb,所以我们需要告诉它。 using data::jsonb 对jsonb执行简单的文本转换。它可以将jsonb转换为文本。
您可以在迁移中使用 change_column .

def up
  change_column :users, :data, :jsonb, using: 'data::jsonb'
end

def down
  change_column :users, :data, :text
end

相关问题