Page 1 sur 1

Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 12 août 2009, 21:28
par abelthorne
Bonsoir,
Avec la fonction mysql_fetch_field utilisée sur une ressource MySQL, on peut connaître la liste des colonnes d'une table et notamment laquelle correspond à la clé primaire (propriété primary_key).
Or, si la requête d'origine comporte un tri (ORDER BY...), mysql_fetch_field n'a plus cette info.

Quel est le meilleur moyen de connaître le nom de la clé primaire d'une table à tous les coups, quelle que soit la requête ? Je sais qu'on peut faire une requête "SHOW COLUMNS FROM lenomdelatable" et tester la valeur de la colonne PRI mais c'est pas terrible de multiplier les requêtes...

EDIT : en fait, je vais développer mon problème parce que je crois que je pars sur une mauvaise analyse.
J'ai deux tables qui sont en relation l'une avec l'autre. Je veux classer les résultats d'une requête sur ces deux tables en fonction de leur relation, qui est basée sur la clé primaire de la première. Pour être plus clair, j'ai ça :
TABLE a
ida (clé primaire)
... (autres colonnes)
TABLE b
idb (clé primaire)
ida (relation avec la clé de a)
... (autres colonnes)

Ma requête sera alors "SELECT * FROM a,b WHERE a.ida=b.ida"
Je trie alors le résultat pour classer les infos entre elles en me basant sur le nom des clés primaires que j'obtiens via mysql_fetch_field.

Sauf que si je rajoute un ORDER BY à ma requête ça ne marche plus (plus de clés primaires) et si j'ai des noms de clés identiques entre plusieurs tables (A : id, B : id et ida, requête "SELECT * FROM a,b WHERE a.id=b.ida"), je ne peux plus me baser sur le nom des clés des tables pour trier mes données.

Il faudrait donc que je puisse classer mes données en fonction des relations obtenues suite à la requête SQL. J'imagine que c'est possible vu que les résultats dans PHPMyAdmin donnent des colonnes spéciales (entourées en orange pour celles qui font partie des clauses WHERE). Mais je ne sais pas trop vers quelles fonctions mysql_* chercher.

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 11:46
par ouckileou
Quel est le but de ce tri ? Une clé primaire sert normalement à identifier les lignes, une clé étrangère à relier une ligne à une autre. Après on trie les résultats par date, par ordre croissant sur une valeur etc. Mais là je ne vois pas ce que tu veux faire.

J'aimerais connaître la finalité de ta demande, il y a peut-être une meilleure façon de faire.

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 12:29
par abelthorne
C'est un peu compliqué. En gros, je cherche à structurer des tables interdépendantes en classes pour pouvoir les manipuler facilement.
Exemple concret : je gère des projets auxquels sont rattachées des photos. J'aurai une table projet et une table photo :
- PROJET
idprojet (clé primaire)
titreprojet
dateprojet

- PHOTO
idphoto (clé primaire)
idprojet (clé secondaire)
fichierphoto

Je fais donc une requête "SELECT * FROM projet,photo WHERE projet.idprojet=photo.idprojet" et je trie le résultat de la requête pour grouper ce qui va ensemble, en fonction de ce que j'appelle la clé secondaire (je ne pense pas que ce soit le bon terme ;) ).
Ça me permet d'obtenir quelque chose de ce genre après tri (2 projets, le premier ayant deux photos et le second une seule) :

Code : Tout sélectionner

[projet][1] idprojet = 1 titreprojet = "Le projet n° 1" dateprojet = 2009-08-01 [photo][37] idphoto = 37 idprojet = 1 fichierphoto = "photo37.jpg" [photo][44] idphoto = 44 idprojet = 1 fichierphoto = "photo44.jpg" [projet][2] idprojet = 2 titreprojet = "Le projet n° 2" dateprojet = 2009-08-05 [photo][23] idphoto = 23 idprojet = 2 fichierphoto = "photo23.jpg"
Je me démerde donc pour faire mon tri en fonction des clés primaires (je crée d'abord un tableau $primaires que je remplis via mysql_fetch_field puis au moment du mysql_fetch_array pour récupérer les valeurs, je compare au tableau $primaires : si c'est dedans et qu'il n'y a qu'une clé, c'est un nouveau projet, s'il y en a deux, ça se rattache au projet correspondant à la clé secondaire, etc.)

Et donc, tout marche bien sauf si dans ma requête je rajoute un ORDER BY (par exemple pour classer les projets par date décroissante) : dans ce cas, mysql_fetch_field ne voit plus de clés primaires et mon tri ne marche pas.

Je ne sais pas si c'est un bug de mysql_fetch_field (j'ai trouvé plusieurs rapports de bugs allant en ce sens, mais ils concernaient peut-être des cas particuliers et ils sont de toute façon censés être corrigés depuis) ou si c'est normal, mais dans les deux cas ça ne m'arrange pas.

D'où ma recherche d'un autre moyen de trouver la clé primaire d'une table, si possible sans faire de requête supplémentaire.

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 14:25
par ouckileou
Avant de passer du tempps sur ce problème, es-tu opposé à l'utilisation d'une solution d'ORM existante et qui ferait tout ça pour toi ?

ORM : http://fr.wikipedia.org/wiki/Mapping_objet-relationnel
Propel : http://propel.phpdb.org
Doctrine : www.doctrine-project.org

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 14:51
par abelthorne
Avant de passer du tempps sur ce problème, es-tu opposé à l'utilisation d'une solution d'ORM existante et qui ferait tout ça pour toi ?
Oui et non. Oui parce qu'il faut apprendre un nouveau système, que ça prend du temps et que je n'en ai pas vraiment. Non parce qu'effectivement si ça résout mes problèmes, forcément, je ne suis pas contre.

Cela dit, il faudrait que ce soit compatible avec mes autres classes et le fonctionnement de mes sites. Si ça fait juste une abstraction des bases manipulées, parfait. S'il faut en plus utiliser des classes propres à ces systèmes pour gérer des formulaires, par exemple, ça ne m'arrange pas du tout.

Je vais aller regarder tout ça.

EDIT : je commence à lire la doc de Doctrine et je vois ça dans les prérequis : "Check that your PHP version is >= 5.2.3 and that you have PDO and the desired drivers installed.".
Je développe un système qui doit pouvoir s'utiliser sur des hébergements mutualisés, donc tout ce qui nécessite des éléments qui ne font pas partie de PHP de base, c'est mort. Je ne sais pas ce qu'est PDO : c'est intégré à PHP ou c'est un module qui s'installe à part ?
Idem pour Propel : il faut obligatoirement PEAR d'installé, il faut un truc qui s'appelle Phing sur le poste de développement...

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 17:40
par ouckileou
Avant de passer du tempps sur ce problème, es-tu opposé à l'utilisation d'une solution d'ORM existante et qui ferait tout ça pour toi ?
Oui et non. Oui parce qu'il faut apprendre un nouveau système, que ça prend du temps et que je n'en ai pas vraiment. Non parce qu'effectivement si ça résout mes problèmes, forcément, je ne suis pas contre.
À toi de voir, mais ce que tu veux faire c'est de l'orm donc bon... perso j'irais vers un système un peu pérenne plutôt qu'un truc custom et potentiellement bancal :)
Et tu risques de passer du temps à régler ton problème, autant qu'à apprendre un système qui pourra te resservir.
Cela dit, il faudrait que ce soit compatible avec mes autres classes et le fonctionnement de mes sites. Si ça fait juste une abstraction des bases manipulées, parfait. S'il faut en plus utiliser des classes propres à ces systèmes pour gérer des formulaires, par exemple, ça ne m'arrange pas du tout.
À voir, je n'ai jamais essayé. Dans Hibernate (Java), tu as des fichiers de mappings, regarde si tu peux faire la même chose dans l'un ou l'autre.
EDIT : je commence à lire la doc de Doctrine et je vois ça dans les prérequis : "Check that your PHP version is >= 5.2.3 and that you have PDO and the desired drivers installed.".
Je développe un système qui doit pouvoir s'utiliser sur des hébergements mutualisés, donc tout ce qui nécessite des éléments qui ne font pas partie de PHP de base, c'est mort. Je ne sais pas ce qu'est PDO : c'est intégré à PHP ou c'est un module qui s'installe à part ?
Idem pour Propel : il faut obligatoirement PEAR d'installé, il faut un truc qui s'appelle Phing sur le poste de développement...
PDO c'est une extension de PHP mais je me demande si c'est pas installé sur la plupart des serveurs : http://fr2.php.net/PDO

Qu'est-ce qui t'empêches d'installer PEAR avec ton outil ? Et Phing c'est pour packager, si c'est requis sur le poste de dév y'en a pas besoin sur le serveur qui fait tourner ton appli où est le problème ? :)

D'où vient la contrainte de ne RIEN installer en plus ? C'est quand même relativement courant les applis qui en nécessitent d'autres, dès que tu veux faire un truc un peu compliqué et/ou ne pas réinventer la roue, je n'y vois rien de choquant. Tu comptes l'installer à beaucoup beaucoup d'endroits différents ?

Re: Trouver la clé d'une table lors d'une requête ordonnée ?

Posté : 14 août 2009, 17:55
par abelthorne
PDO c'est une extension de PHP mais je me demande si c'est pas installé sur la plupart des serveurs : http://fr2.php.net/PDO
"La plupart des serveurs" n'est pas "tous les serveurs". Si je tombe sur un hébergement qui n'a pas PDO, je suis coincé... Je préfère donc me focaliser sur ce qui est présent de base dans PHP.
Qu'est-ce qui t'empêches d'installer PEAR avec ton outil ? Et Phing c'est pour packager, si c'est requis sur le poste de dév y'en a pas besoin sur le serveur qui fait tourner ton appli où est le problème ? :)
Pour le poste de développement, c'est la paresse et le manque de compétences. :)
Je travaille avec XAMPP, alors pour rajouter des extensions, faudrait que je mette en place une vraie solution LAMP, et donc l'administrer, etc.

Enfin bon, c'est pas le plus gros problème. Si c'était le seul obstacle, il ne serait pas bien difficile à franchir.
D'où vient la contrainte de ne RIEN installer en plus ? C'est quand même relativement courant les applis qui en nécessitent d'autres, dès que tu veux faire un truc un peu compliqué et/ou ne pas réinventer la roue, je n'y vois rien de choquant. Tu comptes l'installer à beaucoup beaucoup d'endroits différents ?
Le truc, c'est que tout mon système est fait pour pouvoir développer une solution de backoffice facilement adaptable aux différents sites que je développe. Je n'ai donc aucun contrôle sur les serveurs hébergeant ces sites, ça dépend de mes clients. Ce qui fait que si je tombe sur un hébergement qui n'a pas les extensions nécessaires et sur lequel je ne peux rien installer (en mutualisé, ce qui est le cas d'environ 100 % des sites que je développe), ça complique la situation...