Vous n'êtes pas identifié(e).

#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 smile   :

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 wink

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 smile


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  smile  :

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é!  smile



-[ 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 tongue



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.

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 smile

Hors ligne

Pied de page des forums