sql >> Base de Datos >  >> RDS >> PostgreSQL

Actualización del campo json en Postgres

Sin eval es requerido. Su problema es que no está decodificando el valor como un objeto json.

CREATE OR REPLACE FUNCTION json_update(data json, key text, value json)
RETURNS json AS
$BODY$
   from json import loads, dumps
   if key is None: return data
   js = loads(data)
   # you must decode 'value' with loads too:
   js[key] = loads(value)
   return dumps(js)
$BODY$
LANGUAGE plpythonu VOLATILE;

postgres=# SELECT json_update('{"a":1}', 'a', '{"innerkey":"innervalue"}');
            json_update            
-----------------------------------
 {"a": {"innerkey": "innervalue"}}
(1 row)

No solo eso, sino usar eval para decodificar json es peligroso y poco fiable. No es confiable porque json no es Python, simplemente se evalúa un poco como él la mayor parte del tiempo. No es seguro porque nunca sabes lo que podrías estar evaluando. En este caso, está protegido en gran medida por el analizador json de PostgreSQL:

postgres=# SELECT json_update(
postgres(#    '{"a":1}', 
postgres(#    'a', 
postgres(#    '__import__(''shutil'').rmtree(''/glad_this_is_not_just_root'')'
postgres(# );
ERROR:  invalid input syntax for type json
LINE 4:          '__import__(''shutil'').rmtree(''/glad_this_is_not_...
                 ^
DETAIL:  Token "__import__" is invalid.
CONTEXT:  JSON data, line 1: __import__...

... pero no me sorprendería en absoluto si alguien puede deslizar un eval explotar más allá de eso. Entonces, la lección aquí:no use eval .