PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

विशिष्ट तत्व के लिए JSONB सरणी अद्यतन

पोस्टग्रेएसक्यूएल 11+

अगर आप पहले से ही PostgreSQL v. 11 (नया JSONB रूपांतरण समर्थन टाइप करें ) आपका सबसे अच्छा दांव शायद पर्ल या पायथन में लिखा गया एक कस्टम फ़ंक्शन होगा।

जैसा कि मैं पायथन 3 का पक्ष लेता हूं, यहां एक कार्यात्मक उदाहरण है:

CREATE OR REPLACE FUNCTION jsonb_replace_in_array (val jsonb, path_to_array text[], replacement jsonb, entry_filters jsonb)
    RETURNS jsonb
    TRANSFORM FOR TYPE jsonb
    LANGUAGE plpython3u
AS $$
v_new = val
tmp = v_new
for e in path_to_array:
    tmp = tmp[e]

for item in tmp:
    if (entry_filters is None or entry_filters.items() <= item.items()):
        item.update(replacement)

return v_new
$$;

...जिसे तब निम्न प्रकार से उपयोग किया जा सकता है:

UPDATE configuration
SET
  config = jsonb_replace_in_array(
    config,
    '{data}',
    '{"value":"changed"}'::jsonb,
    '{"oid":"11.5.15.1.4","instance":"1.1.4"}'::jsonb
  )
WHERE config->'data' @> '[{"oid":"11.5.15.1.4","instance":"1.1.4"}]';

तो हाँ, शर्त दोहराई गई है, लेकिन केवल पहली जगह में स्पर्श करने के लिए पंक्तियों की मात्रा को सीमित करने के लिए।

वास्तव में एक सादे PostgreSQL 11 इंस्टॉलेशन पर काम करने के लिए, आपको एक्सटेंशन की आवश्यकता होती है plpython3u और jsonb_plpython3u :

CREATE EXTENSION plpython3u;
CREATE EXTENSION jsonb_plpython3u;

पायथन तर्क समझाया गया:

for e in path_to_array:
    tmp = tmp[e]

...हमें उन प्रविष्टियों की श्रेणी में ले जाता है जिन्हें हमें देखने की आवश्यकता है।

for item in tmp:
    if (entry_filters is None or entry_filters.items() <= item.items()):
        item.update(replacement)

... सरणी में प्रत्येक आइटम के लिए, हम जांचते हैं कि क्या फ़िल्टर मानदंड null है (entry_filters is None =किसी भी प्रविष्टि से मेल खाता है) या क्या प्रविष्टि में कुंजी और मान सहित दिए गए उदाहरण "शामिल हैं" (entry_filters.items() <= item.items() )।

यदि एन प्रविष्टि मेल खाती है, तो दिए गए प्रतिस्थापन के साथ सामग्री को अधिलेखित/जोड़ें।

मुझे आशा है कि यह उस दिशा में जाएगा जहां आप ढूंढ रहे हैं।

JSON संशोधन से संबंधित PostgreSQL की वर्तमान क्षमताओं को देखते हुए यह बहुत जटिल होगा (यदि जटिल नहीं है) और शुद्ध SQL के साथ ऐसा करने के लिए बहुत अधिक ओवरहेड पेश करेगा।

PostgreSQL 9.6+

यदि आपके पास अभी तक संस्करण 11 उपलब्ध नहीं है, तो निम्न फ़ंक्शन स्वयं प्रकार के रूपांतरणों को संभालने की कीमत पर ऐसा ही करेगा, लेकिन इसे पूरी तरह से एपीआई-संगत बनाए रखेगा, इसलिए आप एक बार अपग्रेड करने के बाद, केवल एक चीज जो आपको करनी है फ़ंक्शन को प्रतिस्थापित करता है (इस फ़ंक्शन का उपयोग करके किसी भी कथन में कोई परिवर्तन आवश्यक नहीं):

CREATE OR REPLACE FUNCTION jsonb_replace_in_array (val jsonb, path_to_array text[], replacement jsonb, entry_filters jsonb)
    RETURNS jsonb
    LANGUAGE plpython3u
AS $$
import json

v_new = json.loads(val)
t_replace = json.loads(replacement)
t_filters = json.loads(entry_filters)
tmp = v_new
for e in path_to_array:
    tmp = tmp[e]

for item in tmp:
    if (entry_filters is None or t_filters.items() <= item.items()):
        item.update(t_replace)

return json.dumps(v_new)
$$;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या ऑफ़लाइन वेब एप्लिकेशन के लिए दो अलग-अलग डेटाबेस का उपयोग करना संभव है?

  2. INSERT पंक्ति पर अनुक्रम अपडेट करें

  3. Psql में विदेशी कुंजी बाधाओं के साथ एक तालिका की संरचना को दूसरे में कैसे कॉपी करें?

  4. स्प्रिंग + हाइबरनेट:क्वेरी प्लान कैश मेमोरी उपयोग

  5. बिल्ड समय पर डॉकर छवियों के बीच नेटवर्क कैसे करें?