PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#1 29/03/2012 09:41:37

Merwin
Membre

Requête : copie de donnée hiérarchique

Bonjour à tous,

Je vous expose mon problème :

J'ai une table, appellons la produits, qui contient des lignes décrivant une arborescence de produits :

id  +   parent_id   +   name
----------------------------
1   |               |   Produit #1
2   |           1   |   Produit #2
3   |           2   |   Produit #3

J'ai une table comme ça qui contient environ 100 lignes.
Ensuite, j'ai une seconde table, que l'on appellera produits_souscrits.

La table est identique, avec deux champ en plus : souscrit et client_id :

id  +   parent_id   +   souscrit  + client_id + ... d'autres colonnes comme 'produit_id' qui référence la première table
-------------------------------------------------------------
80   |              |          t  | 150
81   |         80   |          t  | 150
82   |         81   |          f  | 150

L'idée étant simple, quand je souscrit un contrat pour un client, je vais chercher dans ma première tables
les lignes qu'il peut souscrire. Puis je les copies dans ma seconde table.

Il faut lors de la copie "reconstuire" la notion de parent_id, puisque dans la seconde table, les ids sont différents de la première.
Comment faire, sachant qu'ici je cherche la performance ? (Actuellement je fais un tri via du code, puis je fais 80 INSERT dans la nouvelle table).

Merci d'avance,

Hors ligne

#2 29/03/2012 10:01:14

Marc Cousin
Membre

Re : Requête : copie de donnée hiérarchique

Quelque chose m'échappe: pourquoi ne pas tout simplement utiliser les ids de la table produit dans produits_souscrits ?


Marc.

Hors ligne

#3 29/03/2012 10:15:57

Merwin
Membre

Re : Requête : copie de donnée hiérarchique

Malheureusement, je ne suis pas responsable du schéma et je dois faire avec :-(
Je pense qu'a l'origine le problème venait d'OpenERP et de son ORM (plus que médiocre à mon sens).

La consigne étant d'utilisé un maximum l'ORM, la modélisation a été influencée par les possibilités de ORM,
notamment dans ce cas précis l'utilisation de 'child_of' qui permet de tester la parenté via l'ORM, mais qui du coup nécéssite
un champ parent_id dans la table en question...

D'ou ma problématique :-(

Hors ligne

#4 29/03/2012 11:41:11

Marc Cousin
Membre

Re : Requête : copie de donnée hiérarchique

Ok. Qu'appelez vous «reconstruire» la notion de parent_id. Celle que vous montrez n'est pas bonne ?


Marc.

Hors ligne

#5 29/03/2012 12:24:20

Merwin
Membre

Re : Requête : copie de donnée hiérarchique

Par exemple dans la table 1, j'ai un partent_id = 1 pour la ligne 2.
Lorsque je vais copier cette ligne dans ma table 2, elle aura un parent_id égal à 80. Soit l'équivalent dans la table 2 du parent de la ligne 2 dans la table 1.
Ici, parent_id étant, dans chacun des tables, une foreignkey vers elle même.

Aujourd'hui je le fais par le code :

nouvel_id_ligne_1_table_2 = INSERT INTO table2 ....
nouvel_id_ligne_2_table_2 = INSERT INTO table2 .... parent_id = nouvel_id_ligne_1_table_2

Mais ça revient à faire 80 INSERT, d'affilé, puisqu'a chaque fois j'ai besoin de l'ID d'un enregistrement précédent pour le définir comme parent de mon nouvel enregistrement.
C'est très lourd :-/

Hors ligne

#6 29/03/2012 13:46:57

Marc Cousin
Membre

Re : Requête : copie de donnée hiérarchique

On doit pouvoir partir de ça :
with temp as (SELECT *,nextval('table2_id_seq') from table1) select * from temp as t1 left join temp as t1_parent on (t1.parent_id=t1_parent.id)
pour générer tous les id en un seul coup (en partant de l'hypothèse que les id de table2 sont générés par la séquence table2_id_seq).

Il faut une 8.4 pour utiliser un WITH. Le problème, c'est qu'en 8.4, on est coincés à faire des SELECT dans les deux parties. Ce qui veut donc dire continuer à faire des inserts à la main, un par un, ou écrire une petite fonction PL qu'on appelle dans le SELECT.

En 9.1, tout ce qui est WITH (on parle de CTE, comme Common Table Expressions aussi) peut utiliser aussi des ordres de modification:

On peut donc écrire:

with temp as (SELECT *,nextval('table2_id_seq') from table1) insert into table2 select t1.nextval,t1_parent.nextval from temp as t1 left join temp as t1_parent on (t1.parent_id=t1_parent.id);

Il faudra évidemment rajouter une clause where au select (et des alias aux noms de colonne comme nextval, j'ai fait ça comme un cochon). Je l'ai fait pour que ça marche juste avec l'exemple donné.


Marc.

Hors ligne

#7 29/03/2012 13:48:05

Marc Cousin
Membre

Re : Requête : copie de donnée hiérarchique


Marc.

Hors ligne

#8 29/03/2012 14:02:37

Merwin
Membre

Re : Requête : copie de donnée hiérarchique

Je n'ai jamais utilisé WITH, ça a l'air pratique, je reviens vers vous si je ne m'en sort pas !

Merci pour l'aide :-)

Hors ligne

Pied de page des forums