Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#1 07/02/2019 11:24:34
- coucou78187
- Membre
utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Bonjour à tous,
je continue mes tests utilisant postgresql/json ce qui est fort intéresant.
j'ai réussi a avoir un jeu de données avec 500000 lignes avec des "num_matricule (PK)" différents
dans la colonne "valeur JSONB" j'ai inséré pour chaque "num_matricule" 50 codes de type (uuid) comme suit :
do
$$
declare
i record;
begin
for i in 1..500000 loop
INSERT INTO referencement (valeur) VALUES (( '{ "code01": "' || uuid_generate_v4() || '",
"code02": "' || uuid_generate_v4() || '",
"code03": "' || uuid_generate_v4() || '",
...
"code50": "' || uuid_generate_v4() || '"}')::jsonb);
end loop;
end;
$$
;
Ce qui me permet d'avoir une bonne base de données à manipuler pour faire différents tests de performances (CRUD) avec des données aléatoires pour chaque code.
Lorsque je séléctionne (SELECT) différents codes pour un matricule avec la requête suivante :
select num_matricule,
r.valeur->>'code01' as code01,
r.valeur->>'code02' as code02,
r.valeur->>'code03' as code03
from referencement u
where r.num_matricule = 'KJF000000000089745';
j'obtiens:
-[ RECORD 1 ]------------------------------------
num_matricule | KJF000000000089745
code01 | 8314d49b-8ad4-4890-9d20-231a53cc3c17
code02 | 655a3e1d-841c-4453-a758-9705b72bfc86
code03 | bfe2a417-f006-4e33-955d-bbb3066cf220
Temps : 0,529 ms ==> Je trouve celà assez rapide sachant que la PK est utilisée dans ce cas et que j'ai positionné un index GIN sur la colonne "valeur"
Lorsque je voulais tester les update de code pour un num_matricule donné, j'y arrive comme suit avec jsonb_set :
UPDATE referencement SET valeur = jsonb_set(valeur, '{code03}','"bfesdf7-f006-4e33-855d-bhe8766cf225"', true)
where num_matricule = 'KJF000000000089745';
Temps : 2,023 ms ==> je trouve ça rapide même si je n'ai pas de base de comparaison sachant que la PK est utilisée.
ET C'EST LA QUE LES PROBLEMES ARRIVENT :
je désirerai modifier un code pour un num_matricule en utilisant la fonction uuid_generate_v4()
je n'y arrive pas dans ma syntaxe pour que la fonction soit prise en compte et ça prend textuellement 'uuid_generate_v4()' pour un code donnée.
Voilà mes questions :
- Comment faire au niveau de la syntaxe pour que la fonction soit prise en compte et utilisée
- Comment pourrait-on faire pour modifier plusieurs code (environ 15) pour plusieurs num_matricule (1000) pour tester les performances
juste pour info complémentaire :
maintenance_work_mem =1024MB
checkpoint_completion_target = 0.9
effective_cache_size = 2816MB
work_mem = 512MB
wal_buffers = 64MB
shared_buffers = 2048MB
max_connections = 200
RAM: 4G
CPU: 2
Merci à vous et j'espère que ce post pourrait servir à d'autres
Hors ligne
#2 07/02/2019 14:04:29
- gleu
- Administrateur
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Montrez-nous la requête qui ne fonctionne pas, ce sera plus utile
Guillaume.
Hors ligne
#3 07/02/2019 14:58:13
- coucou78187
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Bonjour Guillaume,
C'est vrai, ce sera mieux :
ont été testés:
update referencement set valeur = jsonb_set("valeur", '{"code03"}', '"|| uuid_generate_v4() ||"'::jsonb)
where num_matricule = 'KJF000000000089745';
UPDATE 1
Temps : 2,254 ms
update referencement set valeur = jsonb_set("valeur", '{"code03"}', '" uuid_generate_v4() "'::jsonb)
where num_matricule = 'KJF000000000089745';
UPDATE 1
Temps : 1,683 ms
En réalité, les deux passent bien, seulement elle insèrent les valeurs respectives siuvantes : || uuid_generate_v4() || et uuid_generate_v4() pour le code03 alors que je voudrais si possible UPDATER par une valeur de type "uuid" en utilisant la fonction.
Merci!
Hors ligne
#4 07/02/2019 15:19:03
- gleu
- Administrateur
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Le résultat est logique vu que tu donnes la valeur "|| uuid_generate_v4() ||" à la colonne. Tout ce qui est entre guillemet simple est dans la chaîne. Si tu veux exécuter uuid_generate_v4(), il faudrait mieux faire :
update referencement set valeur = jsonb_set("valeur", '{"code03"}', ('"'||uuid_generate_v4()||'"')::jsonb)
where num_matricule = 'KJF000000000089745';
Guillaume.
Hors ligne
#5 07/02/2019 15:45:46
- coucou78187
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Merci Guillaume,
c'est bien passé!
-[ RECORD 1 ]------------------------------------
num_matricule | KJF000000000089745
created_at | 2019-02-05 16:15:33.987273+01
code03 | 4de8f36d-dc0a-4916-8e1d-e7d154b6afbc
Temps : 0,580 ms
je vais maintenant continuer les tests de perfs pour modifier plusieurs codes pour plusieurs matricules
Merci
Hors ligne
#6 07/02/2019 18:01:25
- coucou78187
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
re Bonjour,
je rencontre maintenant une difficulté pour updater plusieurs codes par exemple:
pour modifier le code03 et le code02
pour le matricule KJF000000000089745 j'ai essayé:
update referencement set valeur = jsonb_set("valeur", '{"code03"}', ('"'||uuid_generate_v4()||'"'), '{"code02"}', ('"'||uuid_generate_v4()||'"'::jsonb))
where num_matricule = 'KJF000000000089745';
update referencement set valeur = jsonb_set("valeur", '{"code03"}', '{"code02"}', ('"'||uuid_generate_v4()||'"')::jsonb)
where num_matricule = 'KJF000000000089745';
ces syntaxes ne fonctionnent pas, je n'ai pas trouver de syntaxe équivalente sur le web.
pensez-vous que celà soit possible ?
j'essaient d'appréhender les opérateurs jsonb mis a disposition
Merci beaucoup!
Hors ligne
#7 07/02/2019 18:20:47
- gleu
- Administrateur
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Ces syntaxes ne fonctionnent pas parce qu'elles n'existent pas. La seule façon, à ma connaissance, est d'appeler jsonb_set deux fois :
jsonb_set(jsonb_set(colonne_json, path, nouvelle_valeur), path2, nouvelle_valeur2);
Moche et certainement peu performant, mais fonctionnel a priori.
Guillaume.
Hors ligne
#8 11/02/2019 11:20:52
- coucou78187
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Bonjour Guillaume,
Merci pour le retour.
Je m'y suis peut être mal pris pour la syntaxe mais j'ai un message d'erreur :
update referencement set valeur = jsonb_set(jsonb_set("valeur", '{"code01"}', ('"'||uuid_generate_v4()||'"')), '{"code02"}', ('"'||uuid_generate_v4()||'"'))
where num_matricule = 'KJF000000000089745';
ERROR: function jsonb_set(jsonb, unknown, text) does not exist
LIGNE 1 : update referencement set valeur = jsonb_set(jsonb_set(valeur,...
^
Comme si le moteur PostgreSQL n'aime pas l'enchainement " (jsonb_set(jsonb_set "
^
Merci,
Bonne semaine!
Dernière modification par coucou78187 (11/02/2019 11:27:04)
Hors ligne
#9 11/02/2019 13:25:10
- gleu
- Administrateur
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Il manque la conversion en jsonb pour le dernier paramètre des deux appels de fonction.
Guillaume.
Hors ligne
#10 11/02/2019 18:56:03
- dverite
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Vous pourriez utiliser une forme plus simple à écrire:
UPDATE nomtable SET col_json = col_json ||
format(
'{"code01":"%s", "code02":"%s"}',
uuid_generate_v4(),
uuid_generate_v4()
)::jsonb;
qui si je comprends bien, fait ce que vous voulez. Cette écriture permet d'ajouter/enlever assez facilement des clefs valeurs.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
#11 13/02/2019 16:50:46
- coucou78187
- Membre
Re : utiliser la fonction uuid_generate_v4() dans un update de champs jsonb
Bonjour Guillaume, Daniel,
Merci beaucoup pour votre aide,
j'ai pu réaliser les tests dont j'avais besoin pour l'étude de cas.
Merci pour l'idée d'utiliser la fonction format()
A tester dans de vrai condition de production
j'essaierai de partager ces expériences et état d'avancement pour partager.
bonne semaine à vous
Hors ligne