Page 1 sur 3

[symfony] récupérer les données d'une jointure

Posté : 07 avr. 2010, 23:17
par marwina32
bonsoir tout le monde,

lors d'une jointure, je n'ai pas pu afficher aucune donnée,
encore je ne sais pas si le problème provient de l'affichage ou bien ma méthode n'a pas pu récupéré les données

si quelqu'un peut m'aider je serai très reconnaissante
//ArticlesTable.class.php
static public function getArticleRupture()
    {
     $q=Doctrine_Query::create()
           ->select('a.codearticle',
                    'a.ref',
                    'a.designationarticle',
                'a.designationlongarticle',
                'a.stockreel',
                'a.minStock',
                'a.stocktheorique',
                'a.gestionstock',
                  'a.bloque',
                    'r.libellerayon')
           ->from('Articles a')
           ->leftJoin('a.Rayon r')
           ->where('r.coderayon = ?', 'a.codearticle')
           ->andWhere('a.GestionStock=?','1')
           ->andWhere('a.Stockreel <=?','a.MinStock');
         return $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
    }
//action.class.php:
public function executeIndex(sfWebRequest $request)
  {
      $this->ruptures = ArticlesTable::getArticleRupture();
  }
et pour mon code d'affichage;
// indexSuccess.php:
<table>
  <caption> Liste des Articles en rupture de stock </caption>
  <thead>
    <tr>
      <th>CodeArticle</th>
      <th>Désignation</th>
      <th>Désignation Longue </th>
      <th>Stock réel</th>
      <th>Stock Min</th>
      <th>Stock théorique</th>
      <th>Géré.Stock</th>
      <th>Bloqué</th>
      <th>Rayon</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($ruptures as $rupture)
      {
    ?>
    <tr>
      <td><?php echo $rupture->getCodeArticle() ?></td>
      <td><?php echo $rupture->getREF() ?></td>
      <td><?php echo $rupture->getDesignationarticle() ?></td>
      <td><?php echo $rupture->getStockreel() ?></td>
      <td><?php echo $rupture->getMinStock() ?></td>
      <td><?php echo $rupture->getStocktheorique() ?></td>
      <td><?php echo $rupture->getGestionStock() ?></td>
      <td><?php echo $rupture->getBloque() ?></td>
      <td><?php echo $rupture->Rayon()->getLibellerayon() ?></td>
    </tr>
    <?php
       }
    ?>
</table>

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 09:23
par zeus
Modération :
Afin d'améliorer la lisibilité de ton message,
pense à utiliser les balises [code] ou [php] (selon le langage utilisé).

Elles sont disponibles au-dessus de la zone de saisie de ton message
lorsque tu postes un nouveau message.

Des indications sont disponibles sur la manière de mettre en forme vos messages dans la FAQ

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 09:33
par zeus
Bonjour,

Une chose me choque pas mal dans ton code : la manière dont tu construis tes requêtes Doctrine.
Est-ce que tu as jeté un coup d'oeil aux requête réellement exécutée ? je pense que tu serais surprises.
De plus, lorsque tu as un soucis de ce type, pour savoir si le problème viens de la récupération des données ou bien de l'affichage, il faut exécuter manuellement la requête pour voir si elle retourne des résultats, et tu es fixée.

Bon, revenons à la requête :
  • Pourquoi lister les champs à sélectionner, plutôt que de laisser Doctrine gérer seul ?
  • la fonction leftJoin() s'occupe de faire elle-même la jointure, alors pourquoi la préciser avec la fonction where() ?
  • pourquoi ne pas remonter des objets, plutôt que des tableaux, puisque tu utilises des objets dans le template
Voilà ce que j'aurais fait pour obtenir tes données :
//ArticlesTable.class.php
static public function getArticleRupture()
{
	$q = Doctrine::getTable('Articles')->createQuery('a')
		->leftJoin(a.Rayon r)
		->where('a.GestionStock = ?','1')
		->andWhere('a.Stockreel <= ?','a.MinStock');
	return $q->execute();
}

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 10:27
par marwina32
bonjour zeus,
vous avez raisons autour des balises, je vais les utiliser la première fois que j'aurai l'occasion :wink:

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 10:42
par marwina32
Bonjour,
merci zeus de votre réponse;

vous avez raison pour le select, je l'ai déjà supprimé du requête,
j'ai déjà testé ma requête depuis Mysql browser, et elle est bien exécutable;
la fonction leftJoin() s'occupe de faire elle-même la jointure, alors pourquoi la préciser avec la fonction where() ?
si je n'utilise pas la fonction where(), j'aurai un message d'erreur:
500 | Internal Server Error | Doctrine_Record_UnknownPropertyException
Unknown method Articles::Rayon
J'ai essayé d'utiliser la fonction innerJoin() sans la préciser avec cette fontion, mais je n'ai pas pu afficher les données
//ArticlesTable.class.php
        static public function getArticleRupture()
	{
	 $q=Doctrine_Query::create()
           ->from('Articles a')
           ->innerJoin('a.Rayon r')
           ->Where('a.GestionStock=?','1')
           ->andWhere('a.Stockreel <=?','a.MinStock');
         return $q->execute();
	}
j'ai eu comme affichage juste le header du tableau

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 10:44
par stealth35
hello, c'est geré pas un YAML ton système (avec foreign) ?

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 10:49
par agité
Bonjour,

Une chose me choque pas mal dans ton code : la manière dont tu construis tes requêtes Doctrine.
Est-ce que tu as jeté un coup d'oeil aux requête réellement exécutée ? je pense que tu serais surprises.
De plus, lorsque tu as un soucis de ce type, pour savoir si le problème viens de la récupération des données ou bien de l'affichage, il faut exécuter manuellement la requête pour voir si elle retourne des résultats, et tu es fixée.

Bon, revenons à la requête :
  • Pourquoi lister les champs à sélectionner, plutôt que de laisser Doctrine gérer seul ?
  • la fonction leftJoin() s'occupe de faire elle-même la jointure, alors pourquoi la préciser avec la fonction where() ?
  • pourquoi ne pas remonter des objets, plutôt que des tableaux, puisque tu utilises des objets dans le template
Voilà ce que j'aurais fait pour obtenir tes données :
//ArticlesTable.class.php
static public function getArticleRupture()
{
	$q = Doctrine::getTable('Articles')->createQuery('a')
		->leftJoin(a.Rayon r)
		->where('a.GestionStock = ?','1')
		->andWhere('a.Stockreel <= ?','a.MinStock');
	return $q->execute();
}
En gros pour toi c'est mieux de faire un select sur tout que de cibler ce dont on a besoin ?

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 10:55
par zeus
Dans l'utilisation qu'elle en fait, oui
Sinon, on se retrouve avec des objets à semi-chargé qui déclenchent de nouvelles requêtes sans qu'on ne sache pourquoi.

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:02
par marwina32
hello, c'est geré pas un YAML ton système (avec foreign) ?
bonjour,
oui, le fichier schema.yml est géré dont le contenu interessant est comme suit:

dans la table Articles

Code : Tout sélectionner

Rayon: foreignAlias: Rayon local: codearticle foreign: coderayon type: many

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:04
par agité
Dans l'utilisation qu'elle en fait, oui
Sinon, on se retrouve avec des objets à semi-chargé qui déclenchent de nouvelles requêtes sans qu'on ne sache pourquoi.
Je sais pas mais en ce moment j'ai vu des requêtes faites comme ça avec des jointures externe comme tu le montre et on arrive vite à des surcharges quant tu joins 3 ou 4 tables bien chargées avec que du select * je sais pas si c'est vraiment une bonne chose. Même en sachant qu'il y a une gestion du cache l'une des premières choses qu'ont ma appris en SQL est l'optimisation des requêtes, donc forcement faire autre que du select *. Maintenant si tu me dis que c'est plus adapté je ne comprends pas. Car tu dis "pour ce cas". Oui mais alors dans quel cas utiliser ta méthode et dans quel autre cas faire de l'optimisation ?

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:10
par stealth35
hello, c'est geré pas un YAML ton système (avec foreign) ?
bonjour,
oui, le fichier schema.yml est géré dont le contenu interessant est comme suit:

dans la table Articles

Code : Tout sélectionner

Rayon: foreignAlias: Rayon local: codearticle foreign: coderayon type: many
ducoup tu pourrais faire juste ca
$q = Doctrine_Core::getTable('Articles')->findBySQL('GestionStock = ? AND Stockreel >= ?', array(1, 'MinStock'));

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:28
par zeus
@agité : faire le choix d'un ORM, c'est s'assoir sur les optimisations de base. Ne serait que le chargement des données en objet, ça a un coup en terme de performance. Heureusement, ce cout se rattrape au niveau de la facilité d'utilisation et de la maintenabilité.
Donc, soit on utilise un ORM, et on est prêt à sacrifier quelques performances, soit la performance est un impératif sur toute une application, et on s'en passe.
La solution intermédiaire et de court-circuiter l'ORM sur les requêtes les plus lourdes et les plus sensibles.

@marwina32 affiche nous la requête générée, et essaye de l'exécuter à la main.

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:37
par marwina32
la requête généré est la suivante:
execute : SELECT a.codearticle AS a__codearticle, a.ref AS a__ref, a.designationarticle AS a__designationarticle, a.designationlongarticle AS a__designationlongarticle, a.prixpublicht AS a__prixpublicht, a.prixconseilleht AS a__prixconseilleht, a.prixhomologuerht AS a__prixhomologuerht, a.prixachatht AS a__prixachatht, a.prixachathtmp AS a__prixachathtmp, a.prixventeht AS a__prixventeht, a.prixventehtmp AS a__prixventehtmp, a.somqteachht AS a__somqteachht, a.valqteachht AS a__valqteachht, a.somqtevenht AS a__somqtevenht, a.valqtevenht AS a__valqtevenht, a.somqteachaccoht AS a__somqteachaccoht, a.valqteachaccoht AS a__valqteachaccoht, a.somqtevenaccoht AS a__somqtevenaccoht, a.valqtevenaccoht AS a__valqtevenaccoht, a.taccoachhtmp AS a__taccoachhtmp, a.taccovenhtmp AS a__taccovenhtmp, a.somqteachescht AS a__somqteachescht, a.valqteachescht AS a__valqteachescht, a.somqtevenescht AS a__somqtevenescht, a.valqtevenescht AS a__valqtevenescht, a.tescachhtmp AS a__tescachhtmp, a.tescovenhtmp AS a__tescovenhtmp, a.deraccordcomach AS a__deraccordcomach, a.derescompteach AS a__derescompteach, a.deraccordcomven AS a__deraccordcomven, a.derescompteven AS a__derescompteven, a.tauxmarge AS a__tauxmarge, a.stockinitial AS a__stockinitial, a.stockreel AS a__stockreel, a.stocktheorique AS a__stocktheorique, a.minstock AS a__minstock, a.maxstock AS a__maxstock, a.cdeclients AS a__cdeclients, a.cdefournisseurs AS a__cdefournisseurs, a.typevaleur AS a__typevaleur, a.remisefrs AS a__remisefrs, a.remise AS a__remise, a.minremise AS a__minremise, a.maxremise AS a__maxremise, a.marge AS a__marge, a.image AS a__image, a.gencode AS a__gencode, a.garentie AS a__garentie, a.typedureegarentie AS a__typedureegarentie, a.observation AS a__observation, a.gestionstock AS a__gestionstock, a.gestionconsigne AS a__gestionconsigne, a.conditionnement AS a__conditionnement, a.numeroserie AS a__numeroserie, a.bloque AS a__bloque, a.etatventetva AS a__etatventetva, a.etatventefodec AS a__etatventefodec, a.etatmouvmente AS a__etatmouvmente, a.nbrutilisé AS a__nbrutilisé, a.codesousfamille_article AS a__codesousfamille_article, a.codetva AS a__codetva, a.codefodec AS a__codefodec, a.codemarque AS a__codemarque, a.codeorigine AS a__codeorigine, a.codeunite AS a__codeunite, a.remise_vente AS a__remise_vente, a.stockphysique AS a__stockphysique, a.test1 AS a__test1, a.test2 AS a__test2, a.test3 AS a__test3, a.test4 AS a__test4, a.valqteremvenht AS a__valqteremvenht, a.somqteremvenht AS a__somqteremvenht, a.valqteremachht AS a__valqteremachht, a.somqteremachht AS a__somqteremachht, a.derremvenht AS a__derremvenht, a.derremachht AS a__derremachht, a.tremvenhtmp AS a__tremvenhtmp, a.tremachhtmp AS a__tremachhtmp, a.derprixachatht AS a__derprixachatht, a.coderayon AS a__coderayon, a.ecartstock AS a__ecartstock, a.prixrevient AS a__prixrevient, a.largeur AS a__largeur, a.epaisseur AS a__epaisseur, a.longeur AS a__longeur, a.nbrepiece AS a__nbrepiece, a.etatachattva AS a__etatachattva, a.pvp AS a__pvp, r.coderayon AS r__coderayon, r.libellerayon AS r__libellerayon, r.codedepot AS r__codedepot FROM articles a INNER JOIN rayon r ON a.codearticle = r.coderayon WHERE (a.gestionstock = ? AND a.stockreel <= ?) - (1, a.MinStock) 
oui, un peu longue!!!

je l'ai éxécutée à la main, et elle m'a affiché les données sélectionnées

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:42
par marwina32
lorsque j'ai précisé les champs à sélectionner:
//ArticlesTables.class.php
        static public function getArticleRupture()
	{
	 $q=Doctrine_Query::create()
           ->select('a.codearticle,
                    a.ref,
                    a.designationarticle,
	            a.designationlongarticle,
	            a.stockreel,
	            a.minStock,
	            a.stocktheorique,
	            a.gestionstock,
          	    a.bloque,
            	    r.libellerayon')
           ->from('articles a')
           ->innerJoin('a.Rayon r')
           ->Where('a.GestionStock=?','1')
           ->andWhere('a.Stockreel <=?','a.MinStock');
         return $q->execute();
	}
la requête générée s'est optimisée:
SELECT a.codearticle AS a__codearticle, a.ref AS a__ref, a.designationarticle AS a__designationarticle, a.designationlongarticle AS a__designationlongarticle, a.stockreel AS a__stockreel, a.minstock AS a__minstock, a.stocktheorique AS a__stocktheorique, a.gestionstock AS a__gestionstock, a.bloque AS a__bloque, r.coderayon AS r__coderayon, r.libellerayon AS r__libellerayon FROM articles a INNER JOIN rayon r ON a.codearticle = r.coderayon WHERE (a.gestionstock = ? AND a.stockreel <= ?) - (1, a.MinStock)

Re: [symfony] récupérer les données d'une jointure

Posté : 08 avr. 2010, 11:46
par zeus
Attention : moins longue != optimisée

Si la requête te retourne les données, c'est que le soucis se situe au niveau de l'action ou du template