IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ORM PHP Discussion :

[Doctrine] Hydratation d'objets sur une autre table que celle du FROM


Sujet :

ORM PHP

  1. #1
    Invité
    Invité(e)
    Par défaut [Doctrine] Hydratation d'objets sur une autre table que celle du FROM
    Bonjour,

    Depuis quelques temps je me questionne sur un comportement de Doctrine, et n'arrivant pas à trouver de résultat, je me permets de vous demander votre avis.

    Sur mon application, je suis souvent amenés à faire des requêtes qui ont la forme suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $coms = Doctrine_Core::getTable('Commentaire')
    ->createQuery('c')
    ->join('c.article a')
    ->join('a.Redacteurs r')
    ->where('r.quelquechose = ?', $quelquechose);
    On veut donc récupérer les commentaires des articles dont le rédacteur répond à une certaine condition. On part de la table commentaire ( car on veut obtenir une collection de commentaires à la fin ), puis on la join à tous les articles puis à tous les rédacteurs, et enfin on réduit les résultat avec la condition.

    Cette requête serait beaucoup plus optimisée avec les jointures dans cet ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $coms = Doctrine_Core::getTable('Redacteur')
    ->createQuery('r')
    ->select('c.*')
    ->join('r.Article a')
    ->join('a.Commentaires c')
    ->where('r.quelquechose = ?', $quelquechose);
    De cette manière, le nombre de tuples manipulés par les jointures est beaucoup plus réduit, vu que la restriction sur le rédacteur va s'effectuer dés le début.

    Le problème est que de cette manière, j'obtient un magnifique :
    The root class of the query (alias r) must have at least one field selected.
    Existe-t'il une solution pour garder cet ordre dans les jointures et obtenir tout de même une collection doctrine d'objets commentaire ?

    Merci !
    Dernière modification par Invité ; 24/07/2010 à 18h03.

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Qui te retourne le message d'erreur ? Mysql ? Doctrine ? Symfony ?

    Je présuppose que le message vient de Doctrine. On aurait donc une limitation du moteur. N'est-il pas envisageable de mettre un des champs de rédacteur dans la réponse ?

    Si non, peut-on envisager de faire un group by article et un having pour le qhere sur le rédacteur ?
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  3. #3
    Invité
    Invité(e)
    Par défaut
    Le message est retourné par doctrine, mais disons que j'attendais cette erreur car SI cette fonctionnalité existe, ce n'est dans tout les cas pas la bonne méthode/syntaxe pour en faire appel.

    Si je rajoute un champ de Rédacteur, la requête va fonctionner et doctrine me retournera une Doctrine_Collection d'objets Redacteur (complets par ailleurs), avec leurs articles et leurs commentaires préchargés.

    Si non, peut-on envisager de faire un group by article et un having pour le qhere sur le rédacteur ?
    Peux-tu préciser la requête à laquelle tu penses ( en SQL pur si tu veux ).
    Mais à première vue je ne pense pas que ce soit une solution.

    J'ai cherché au niveau des méthodes d'hydratation de doctrine et/ou de PDO, mais pour le moment je ne trouve rien.
    C'est étonnant car cela entraine des requête grossièrement lourde ( dans certaines situations ), alors qu'elles pourraient être facilement optimisées.

  4. #4
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Je ne vois pas où est le problème d'avoir l'id ou n'importe quel autre informations sur le rédacteur dans le résultats de la requête. Cela ne devrait rien changer au résultat obtenu.

    L'hydratation n'intervient qu'après le retour des données, il ne peut donc être en cause ici, il faudra attendre d'avoir les données pour s'inquiéter de l'hydratation.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Mon "problème" à ce niveau est que de cette manière, pour obtenir les commentaires, je vais devoir passer par un code du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $redacteurs = Doctrine_Core::getTable('Redacteur')
    ->createQuery('r')
    ->select('c.*, r.id') // doctrine transforme en c.*, r.*
    ->join('r.Article a')
    ->join('a.Commentaires c')
    ->where('r.quelquechose = ?', $quelquechose); 
     
    $coms = array();
    foreach ($redacteurs as $redacteur) {
      $articles = $redacteur->getArticles();
      foreach ($articles as $article) {
        $coms += $article->getCommentaires(); // Concaténation d'array, je suis pas sûr de moi là
      }
    }
    Donc on se rend compte que pour obtenir le tableau de commentaires, la requête SQL va retourner les données des rédacteurs et des articles ( les tables intermédiaires ), ce qui ne m'intéresse pas du tout.

    Ce que j'aimerais ( et je le répète, je ne sais pas si doctrine et/ou PDO le gère ), c'est retourner directement les infos des commentaires, en zappant le reste ( les id utilisés pour les jointures au minimum ).

  6. #6
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Si la requête fonctionne, et si les données ne doivent qu'être affichées, la solution est (enfin) dans l'hydratation.

    Tu trouveras les différentes méthode dans la doc de doctrine, partie hydratation. Je pense que la méthode "scalar" devrait répondre à ta demande.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  7. #7
    Membre averti
    Inscrit en
    Août 2007
    Messages
    360
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 360
    Points : 396
    Points
    396
    Par défaut
    Sinon tu peux créer une Doctrine_Collection('de_ton_modele') et la remplir en faisant un ->add(Record) dans ton foreach, mais c'est sur que ce n'est pas très optimisé.

    EDIT : Tu peux aussi utiliser les foreignAlias (dans ton YAML)

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/01/2014, 01h24
  2. Réponses: 5
    Dernier message: 10/12/2012, 12h20
  3. Réponses: 2
    Dernier message: 12/01/2011, 08h21
  4. Réponses: 7
    Dernier message: 01/09/2007, 15h27
  5. pb d'insertion avec un SELECT sur une autre table
    Par epeichette dans le forum Requêtes
    Réponses: 3
    Dernier message: 03/01/2005, 22h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo