sql >> Databáze >  >> RDS >> PostgreSQL

Aktualizace pole JSONB pro konkrétní prvek

PostgreSQL 11+

Pokud již používáte PostgreSQL v. 11 (kvůli nový JSONB podpora konverze typu ) nejlepší by pravděpodobně byla vlastní funkce napsaná v Perlu nebo Pythonu.

Protože preferuji Python 3, zde je funkční příklad:

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
$$;

...který pak lze použít následovně:

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"}]';

Takže ano, podmínka je duplikovaná, ale pouze za účelem omezení počtu řádků, kterých se lze dotknout.

Chcete-li skutečně pracovat na jednoduché instalaci PostgreSQL 11, potřebujete rozšíření plpython3u a jsonb_plpython3u :

CREATE EXTENSION plpython3u;
CREATE EXTENSION jsonb_plpython3u;

Logika Pythonu vysvětlila:

for e in path_to_array:
    tmp = tmp[e]

...dostaneme se k řadě položek, na které se musíme podívat.

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

...pro každou položku v poli zkontrolujeme, zda je kritérium filtru null (entry_filters is None =odpovídá libovolné položce) nebo zda položka „obsahuje“ poskytnutý příklad včetně klíčů a hodnot (entry_filters.items() <= item.items() ).

Pokud se položka en shoduje, přepište/přidejte obsah poskytnutou náhradou.

Doufám, že to jde směrem, který hledáte.

Když se podíváme na současné možnosti PostgreSQL související s modifikací JSON, bylo by to velmi složité (ne-li komplikované) a znamenalo by to spoustu režie, aby bylo možné totéž udělat s čistým SQL.

PostgreSQL 9.6+

V případě, že ještě nemáte k dispozici verzi 11, následující funkce udělá totéž na úkor zpracování převodů typů sama, ale zachová ji zcela kompatibilní s API, takže po upgradu budete muset udělat jedinou věc je nahradit funkci (nevyžaduje se žádná změna příkazů používajících tuto funkci):

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. Oracle Database Explorer:bezplatné školení a akreditace

  2. Používání trvalého připojení PHP-MySQL ke spuštění blogu WordPress

  3. JSON Vložit do tabulky MySQL nebo aktualizovat, pokud existuje

  4. Vylepšení dotazu pomocí velkého množství vnitřních spojení s tabulkou klíč/hodnota wp_postmeta