web-dev-qa-db-ja.com

表示するPostgresql json列

このようなテーブルがあります

id |   json_column
---+------------
 1 | {"text1":"a", "text2":"b", "text3":"c", ....}
 2 | {"text1":"b", "text2":"c", ....}

そして、私はそれがこのようになりたいです

text1 | text2 | text3 | ....
a     | b     | c     | ....
b     | c     | d     | ....

この結果を得るために見つけたバリアントの1つは、json_populate_record()を使用して新しいタイプxを(text1 text、text2 text、text3 text、...)として作成することです。

select (json_populate_record(null::x, json_column)).* from table

上記のようなタイプを作成せずにこれを行う別の方法はありますか?すべての新しい列にテキストタイプを含めることができるので、おそらくショートカットはありますか?

私の問題は、aaaa_bbbb_cccc_dの形式で1つのjsonフィールドに50個のキーがあるため、これを1つのタイプで手動で作成すると時間がかかることです

9.5.4を使用しています

6
CherrySkizz

暗黙的に「ダミータイプ」を介して、または明示的に、たとえば、選択リストですべてのJSON属性を指定する手間を省く方法はありません。このようなものを使用して:

select json_column ->> 'text1' as text1, 
       json_column ->> 'text2' as text2, 
       ... 
from the_table;

あなたができることは、JSONドキュメントの個別の属性に基づいてすべての属性を持つビューを自動的に作成することで、これをより簡単にすることです。

次のコードは、JSON列のすべての個別のキーでビューを再作成します。

do
$$
declare
  l_keys text;
begin
   drop view if exists v_json_view cascade;

   select string_agg(distinct format('json_column ->> %L as %I',jkey, jkey), ', ')
     into l_keys
   from the_table, json_object_keys(json_column) as t(jkey);

   execute 'create view v_json_view as select '||l_keys||' from the_table';
end;
$$
;

すべてのjsonドキュメントのキーのリストが変更されるたびに、上記を実行する必要があります。 理論的にはこれはトリガーで実行できますが、そのテーブルで多くの更新を実行する場合は、おそらくお勧めできません。

JSONキーの総数がやや「安定」している場合は、cronジョブをスケジュールして、定期的にそのビューを再作成できます。

テーブルまたはビューの列の最大数によっても制限されます。約よりも多くの(個別の)キーがある場合。上記の1600(多分少ない)willは失敗します。