"ERROR: विकृत सरणी शाब्दिक" जब JSON_to_record का उपयोग JSON सरणी तत्व के साथ Postgr 9.4 में किया जाता है


9

इस मुद्दे को अच्छी तरह से दिखाता है:

जब कॉलम बी टाइप टेक्स्ट का हो, और एरे का न हो, तो निम्न कार्य करता है:

select * 
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}') 
    as x(a int, b text, d text);

 a |         b          | d
---+--------------------+---
 1 | ["hello", "There"] |

लेकिन अगर मैं bकॉलम को एक सरणी के रूप में परिभाषित करता हूं, तो मुझे यह त्रुटि मिलती है:

select * 
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}') 
    as x(a int, b text[], d text)

ERROR:  malformed array literal: "["hello", "There"]"
DETAIL:  "[" must introduce explicitly-specified array dimensions.

मैं JSON सरणी को लक्ष्य स्तंभ प्रकार के पोस्टग्रेज सरणी में बदलने के लिए कैसे मना / कर सकता / सकती हूं json_to_record(या json_populate_record)?

जवाबों:


6

क्रिस के जवाब में बस थोड़ा सा बदलाव:

SELECT a, translate(b, '[]', '{}')::text[] AS b, d
FROM json_to_record('{"a": 1, "b": ["hello", "There"], "c": "bar"}')
AS x(a int, b text, d text);

यह विचार समान है: JSON सरणी को एक सरणी में मालिश करें - इस मामले में, एक सरणी शाब्दिक के माध्यम से। एक बिट क्लीनर दिखने वाले कोड के अलावा (हालांकि मुझे यह पसंद है, रेगेक्स आमतौर पर इस संबंध में ज्यादा मदद नहीं करता है :), यह बहुत तेजी से लगता है:

CREATE TABLE jsonb_test (
    id serial,
    data jsonb
);

INSERT INTO jsonb_test (id, data)
SELECT i, format('{"a": %s, "b": ["foo", "bar"], "c": "baz"}', i::text)::jsonb 
FROM generate_series(1,10000) t(i);

SELECT a, string_to_array(regexp_replace(b, '\[*\"*\s*\]*','','g'),',') AS b, d
FROM jsonb_test AS j, 
LATERAL json_to_record(j.data::json) AS r(a int, b text, d text);

-- versus 

SELECT a, translate(b, '[]', '{}')::text[] AS b, d
FROM jsonb_test AS j, 
LATERAL json_to_record(j.data::json) AS r(a int, b text, d text);

इस डेटासेट और मेरे परीक्षण बॉक्स पर, रेगेक्स संस्करण दिखाता है और औसत निष्पादन समय 300 एमएस है , जबकि मेरा संस्करण 210 एमएस दिखाता है ।


1

यह सबसे सुरुचिपूर्ण समाधान नहीं हो सकता है, लेकिन यह आपके मुद्दों को ठीक करेगा ...

SELECT a,string_to_array(regexp_replace(b, '\[*\"*\s*\]*','','g'),',') AS b,d
FROM json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}')
AS x(a int, b text, d text);

यह बहुत सरल है कि यह कैसे काम करता है:

सबसे पहले , textस्ट्रिंग को अंदर ले जाएं b, और इसे उपयोगी जानकारी के लिए पट्टी करें। यह के regexp_replace()रूप में उपयोग करके किया जाता है

regexp_replace(b, '\[*\"*\s*\]*','','g')

के सभी उदाहरणों को दूर करने [, ", ], और किसी भी खाली स्थान के अक्षर, या अधिक विशेष रूप से, के साथ इन पात्रों में से किसी उदाहरण को बदलने के लिए '', और ध्वज का उपयोग करके यह विश्व स्तर पर, संकेत लागू करने के लिए 'g'

अगला , बस के string_to_array()रूप में उपयोग करके एक सरणी में स्ट्रिंग को विभाजित करें

string_to_array(your_string,',')

जहां इस मामले your_stringमें बस ऊपर का परिणाम है regexp_replace()। दूसरा तर्क ','यह इंगित करता है string_to_array()कि आइटम अल्पविराम से अलग किए गए हैं।

यह text[]आपके इच्छित प्रविष्टियों वाले क्षेत्र का उत्पादन करेगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.