web-dev-qa-db-fra.com

Comment vérifier si une clé json existe dans Postgres?

Disons que j'ai un JSON qui ressemble à ceci:

some_json = {'key_a': {'nested_key': 'a'},
             'key_b': {'nested_key': 'b'}}

Notez que key_a et key_b sont des clés facultatives mappées sur des dictionnaires et peuvent ou non exister.

J'ai une fonction qui vérifie si une clé externe existe dans some_json et renvoie un booléen.

CREATE FUNCTION key_exists(some_json json, outer_key text)
RETURNS boolean AS $$
BEGIN
    RETURN (some_json->outer_key IS NULL);
END;
$$ LANGUAGE plpgsql;

Je reçois l'erreur suivante:

ProgrammingError: operator does not exist: json -> boolean

Pourquoi outer_key équivaut-il à un booléen? Quelle est la syntaxe appropriée pour effectuer cette vérification?

18
Teboto

Votre fonction fait exactement le contraire du nom, mais la solution consiste à ajouter ( et ) autour du some_json->outer_key.

Le voici pleinement fonctionnel, et correspondant au nom de votre fonction (notez la NOT devant la NULL).

CREATE FUNCTION key_exists(some_json json, outer_key text)
RETURNS boolean AS $$
BEGIN
    RETURN (some_json->outer_key) IS NOT NULL;
END;
$$ LANGUAGE plpgsql;

Quelques tests:

select key_exists('{"key_a": {"nested_key": "a"}, "key_b": {"nested_key": "b"}}'::json, 'key_a');
 key_exists 
------------
 t
(1 row)

Et ici quand une clé n'existe pas:

select key_exists('{"key_a": {"nested_key": "a"}, "key_b": {"nested_key": "b"}}'::json, 'test');
 key_exists 
------------
 f
(1 row)
17
X-Istence

Vous pouvez aussi utiliser le '?' opérateur comme ça:

SELECT '{"key_a":1}'::jsonb ? 'key_a'

Et si vous avez besoin d'interroger par clé imbriquée, utilisez comme ceci:

SELECT '{"key_a": {"nested_key": "a"}}'::jsonb -> 'key_a' ? 'nested_key' 

Voir http://www.postgresql.org/docs/9.5/static/functions-json.html

NOTE: uniquement pour le type jsonb.

28
DaL

Pour vérifier si la clé existe ou non, vous pouvez utiliser l'opérateur -> ceci est utilisé pour obtenir le champ d'objet d'objet JSON par clé Par exemple: 

actual json data in column(attribute): {
    "active": "t",
    "email_address": "[email protected]",
    "pin": "2233"
}

SELECT attributes::json->'email_address'
FROM entity
WHERE entity_id = 55;

Vous pouvez également rechercher des clés via les opérateurs #> et # >>.

Récupère le champ d'objet JSON en tant que texte: '{"a": 1, "b": 2}' :: json - >> 'b' en utilisant l'opérateur - >>

0
Piyush Sharma