2017-04-06 84 views
0

我有一些JSON存儲在Postgresql 9.5數據庫的json數據庫列中。 JSON來自外部應用程序,我不控制它的結構。我需要寫一個查詢flattens的JSON。如何使用Postgresql的json_to_record屬性超過63個字符?

簡單的情況下工作:

SELECT * FROM json_to_record('{"a": "this is a", "b": 25, "c": "this is c"}') as x(a text, b int, c text);

a | b | c
-----------+----+----------- this is a | 25 | this is c

然而,一些JSON的包含超過63個字符長的密鑰。在這種情況下,據我所知道的,記錄定義時創建PostgreSQL的截斷的標識,因此它不再是JSON密鑰相匹配,因此該列始終爲空:

SELECT * FROM json_to_record( '{"a": "this is a", "b": 25, "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute": "this is c" }') as x(a text, b int, this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute text);

NOTICE: identifier "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute" will be truncated to "this_identifier_is_going_to_be_longer_than_sixty_three_characte" a | b | this_identifier_is_going_to_be_longer_than_sixty_three_characte -----------+----+----------------------------------------------------------------- this is a | 25 |

使用在記錄中的截斷版本不起作用:

SELECT * FROM json_to_record( '{"a": "this is a", "b": 25, "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute": "this is c" }') as x(a text, b int, this_identifier_is_going_to_be_longer_than_sixty_three_characte text);

a | b | this_identifier_is_going_to_be_longer_than_sixty_three_characte -----------+----+----------------------------------------------------------------- this is a | 25 |

什麼是最好的方式來獲取數據,而不用重新編譯Postgresql與更大的NAMEDATALEN

使用json_to_record的原因是我有一個包含數千行包含json列和鑑別器列的行的表。我想創建一個看起來像一個正常的錶行,在鑑別列中的特定值的觀點:

CREATE OR REPLACE VIEW myview AS SELECT id, date_created, date_modified, status, uuid, r1.*, FROM mytable, jsonb_to_record(json_col) as r1( "columnA" text, "columnB" int, ""this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute" text) WHERE parent_fkey = 20 AND status = 'Published'

+0

可能只通過改變所有的鍵 - 準備之前'json_to_record' –

+0

或者一些解決方法嗎?你想用'json_to_record'來實現什麼? –

+0

@VaoTsun我有一個包含數千行包含json列和鑑別器列的表。我想創建一個視圖,看起來像一個普通表的行在鑑別器列 – rhunwicks

回答

0

車輪可以在這裏爲了有助於走了過來 - 你可以在「重命名」鍵上飛行。如果你有幾個不同的關鍵字截斷爲相同的63個字符,它會失敗,但你知道。無論如何,

樣本:

t=# create table so41(i int,j json); 
CREATE TABLE 
Time: 5.736 ms 
t=# insert into so41 select 1,'{"a": "this is a", 
t'#  "b": 25, 
t'#  "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute": "this is c" 
t'# }'; 
INSERT 0 1 
Time: 0.989 ms 
t=# insert into so41 select 2,'{"a": "this is a1", 
    "b": 27, 
    "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute": "this is c1" 
    }'; 
INSERT 0 1 
Time: 4.027 ms 

輪:

t=# with tt as (
    with t as (
    select *,j->json_object_keys(j) val,substr(json_object_keys(j),1,63) k 
    from so41 
) 
    select concat('{',string_agg(concat('"',k,'":',val),',') over (partition by i), '}')::json,i,j 
    from t 
) 
select i,r1.* 
from tt 
join json_to_record(concat) as r1(a text, b text, this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute text) on true; 
NOTICE: identifier "this_identifier_is_going_to_be_longer_than_sixty_three_characters_attribute" will be truncated to "this_identifier_is_going_to_be_longer_than_sixty_three_characte" 
i |  a  | b | this_identifier_is_going_to_be_longer_than_sixty_three_characte 
---+------------+----+----------------------------------------------------------------- 
1 | this is a | 25 | this is c 
1 | this is a | 25 | this is c 
1 | this is a | 25 | this is c 
2 | this is a1 | 27 | this is c1 
2 | this is a1 | 27 | this is c1 
2 | this is a1 | 27 | this is c1 
(6 rows) 

Time: 0.574 ms 
相關問題