Forum Programmation.autre Soucis avec postgreSQL

Posté par  .
Étiquettes :
0
18
jan.
2005
Hello forum !
Dans le cadre d'un projet applicatif professionnel, j'ai rédigé quelques pages php permettant d'accéder aux enregistrements d'une base de données postgreSQL. Jusqu'ici tout va bien. Bon, sauf que :
- lorsque j'ai créé ma base et mes tables, j'ai défini des clefs primaires sur ces dernières.
- Les clefs primaires ne sont pas modifiables
- Les clefs primaires permettent d'identifier de manière unique un enregistrement.
Par conséquent, j'aimerais récupérer la liste des champs formant la clef primaire d'une table, de façon à créer dynamiquement des requêtes de suppression et de modification qui soient un tant soit peu correctes. Mais voilà, je ne sais pas comment procéder. Je ne sais pas où pêcher l'information.
J'ai regardé un peu dans les tables/vues internes à postgres (version 7.3.4 au passage), mais je n'ai rien trouvé d'exploitable.
Les numéros des champs constituant la clef primaire sont renseignés dans le champ indkey (sous forme d'int2vector) de la table système pg_index, mais comme il n'y a pas de fonctions et d'opérateurs sur ce type, ce n'est pas exploitable.
Par ailleurs, il y a une vue système nommée pg_indexes qui renvoie, entre autres, la commande sql de définition de l'index, et donc les champs constituants la clef primaire sont renseignés, dans une chaîne de caractères... Bref, pas trop exploitables non plus.
Auriez-vous d'autres pistes à me donner, un manière fiable, sûre, sans équivoque, de récupérer ces foutus champs constituant une clef primaires ?
Pour l'instant, je découpe la commande sql citée ci-dessus, mais c'est pas franchement génial. Je suis preneur de toute idée, suggestion, etc.
Merci.
  • # Précision, petite précision

    Posté par  (site web personnel) . Évalué à 3.

    Je n'ai pas vraiment saisi ce que tu voulais faire :
    . tu veux récupérer le nom du champ correspondant à la clé primaire pour chaque table ?
    . tu veux récupérer toutes les valeurs des champs correspondant au clés primaires pour chacune des tables (possible à partir du précédent)?

    À priori, un index est créé pour chaque clé primaire donc pour chaque table (tablename), tu dois pouvoir trouver dans le champ indexdef le nom de ta clé primaire (table pg_indexes).
    Il y a certainement mieux. C'est ce que j'ai testé en trente secondes :
    # SELECT * from pg_indexes where tablename='foo';
    schemaname | tablename | indexname | indexdef
    ------------+-----------+-----------+----------------------------------------------------------
    public | foo | foo_pkey | CREATE UNIQUE INDEX foo_pkey ON foo USING btree (id_foo)
    ou id_foo est la clé.
    • [^] # Re: Précision, petite précision

      Posté par  (site web personnel) . Évalué à 3.

      Oups, j'avais mal lu ton post. bon, ça aura au moins l'avantage d'expliciter ton dernier paragraphe. D'ailleurs, c'est effectivement une vue, pas une table.
    • [^] # Re: Précision, petite précision

      Posté par  . Évalué à 2.

      En gros, c'est ça, sauf que ce qui m'intéresse, c'est ce qui est entre les parenthèses du dernier champ retourné par ta requête : id_foo.
      Dans ce cas, c'est simple, y'a qu'un champ !
      Pour être plus clair (?) je voudrais obtenir à peu près ça :

      select attname from pg_attribute, pg_class, pg_index where attrelid = pg_class.oid and relname = 'spe' and attnum > 0 and pg_index.indrelid = pg_class.oid and attnum in (indkey[0], indkey[1], indkey[2]);


      Sans préciser la liste des intkey[] dans le in... C'est ce que j'ai trouvé de plus "propre", mais ç'est pas encore ce que je veux. Après tout, rien n'empêche de créer une table comportant 300 attributs, parmis lesquels 50 constituent la clef primaire.... Et je me vois mal compléter ce qui est entre les parenthèses de ma requête...

      Quoi qu'il en soit, merci pour ta réponse.
  • # n'importe quoi ?

    Posté par  . Évalué à 3.

    Bon je n'ai peut-être absolument rien capté à la nature de ton problème mais ça pourrait servir un jour (sait-on jamais ?).

    Je pense que tu te compliques la vie un peu trop !
    Si j'ai bien compris (c'est rare mais ça arrive), tu as des clés primaires multi-colonnes ... c'est pas toujours évident ensuite de repérer les enregistrements à modifier ou supprimer ; à moins de faire des requêtes spécifiques à chaque table précisant en le n-uplet primaire.

    Si tel est le cas, pourquoi n'utilises-tu pas le champ caché "oid" présent dans toutes les tables PostgreSQL ?
    Ainsi, en passant une valeur hidden dans tes pages html (ou php), tu es toujours sûr qu'il s'agit d'un seul et unique enregistrement, qu'importe la complexité de la clé primaire.

    Ce n'est peut-être pas super portable (d'une bd à une autre) ou très propre à ton sens mais ça pourrait faire l'affaire non ?

    P.S : Ne pas taper (ou moinser récursivement) si mon truc est foireux !
    • [^] # Re: n'importe quoi ?

      Posté par  . Évalué à 2.

      C'est loin d'être idiot comme proposition ! Je n'y avais vraiment pas pensé. Dans un cas pratique genre phppgsql, il est probable d'ailleurs que ce soit ainsi géré (j'ai jamais fouillé les sources, mais sait-on jamais...).
      Dans mon cas de figure, cependant, ça implique trop de modifs, et surtout, il me semble que les oid ne sont fas fiables, et surtout, compliqueraient un peu les choses.
      Dans mon appli, par exemple, si je veux effacer une ligne dont la clef primaire vaut 148, c'est facile. L'utilisateur rentre 148 dans le champ idoine du formulaire, tape sur supprimer, et hop, le tour est joué.
      Dans ce que tu proposes, il faudrait d'abord chercher l'oid de l'enregistrement dont la clef vaut 148, puis effacer celui-ci.... Pas génial, mais l'idée est cependant séduisante pour les cas de modifications...


      P.S : Ne pas taper (ou moinser récursivement) si mon truc est foireux !

      Hé bien, je ne vois pas pourquoi je moinserai le post de quelqu'un qui s'est penché sur mon problème et a tenté (d'une manière sensée) de le résoudre ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.