Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/01/2012, 15h59   #1
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Par défaut Symfony sfDoctrinePager et LIMIT de la requête

Bonjour,

J'ai une table mysql avec 5000 lignes. Je veux extraire les dernières 1000 et les paginer avec sfDoctrinePage() à raison de 10 par page.

Le problème est que pager->setQuery() ignore mon LIMIT et me retourne les 5000 lignes de la table

Code :
1
2
3
$query = "select * from my_table limit 1000";
$this->pager = new sfDoctrinePager('ma_table', 10);
$this->pager->setQuery($query);
Merci pour votre aide
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h06   #2
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
Je crois que tu n'as pas compris le fonctionnement du pager.

C'est lui qui gère le limit.
La requête peu avoir toutes les conditions que tu veux mais pas le limit.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h13   #3
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Merci, c'est ce que j'ai cru comprendre, les LIMIT sont réécris.

Mais comment faire dans ce cas pour éviter de charger toutes les 5000 lignes de ma table?
Il y a bien cette méthode mais elle semble ne rien faire:
Code :
$this->pager->setMaxRecordLimit(1000);
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h21   #4
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
Si c'est le pager qui gère ton limit il ne va pas charger les 5000 résultat mais juste le nombre de résultat par page

c'est pour ça que tu as un limit et un offset.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h28   #5
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Mais pour savoir combien de pages retourne ma requête et afficher les liens de navigation entre les pages, genre "<< 1, 2, 3...x >>", il doit bien aller chercher toutes les 5000 lignes, non? Sinon comment savoir le nombre de pages à afficher?

Ce qui, j'ajoute, ralenti sensiblement ma page
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h36   #6
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
ben en faisant un count () de la condition initiale
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 17h56   #7
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Merci

Comment je fais si je veux quand même limiter le nombre de mes pages?
Avec mes 5000 lignes, j'ai 500 pages à raison de 10 par page.
Mais je veux juste les dernières 1000 lignes, donc juste 100 pages à raison de 10 par page.
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 18h04   #8
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
c'est pas possible si ta requête à la base te retourne 5000 résultats c'est que tes conditions sont mauvaises.

Et comment peux tu n'afficher que 1000 résultats alors que ta requête base en retourne 5000 ????
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 08h58   #9
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Ma requête de base ne retourne pas 5000 lignes, c'est la table qui en contient 5000.
Le problème c'est que sfDoctrinePager('ma_table') prend tout ce qu'il y dans la table lors de la création de l'instance. Je cherche donc un moyen de contourner ce comportement par défaut et ne retourner que les 1000 dernières lignes.

J'ai essayé: $this->pager->getQuery()->limit(1000) mais rien.

La documentation semble dire que $this->pager->setMaxRecordLimit(1000) est fait pour ça, mais rien non plus de ce côté
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 11h35   #10
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
Voila la doc http://www.symfony-project.org/jobee...Doctrine/fr/07

Si tu force ton limit tu vas retourne tes 1000 résultats dans une page.

Doctrine n'appelle pas du tout tes 5000 résultats, il construit la requête en ajoutant un limit. donc ça c'est sur qu'il te retournera au max que le nombre que tu as mis indiqué.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 11h50   #11
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Là franchement ya un truc qui m'échappe grave, je ne vois pas où FORCER mon limit à 1000.
Je l'ai mis dans le modèle, mais marche pas non plus. Comment le forcer à ne retourner que les derniers 1000 et les paginer ensuite?

Voici mon code:
La table Amis a 5000 lignes.

Model:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
class AmisTable extends Doctrine_Table {
  public static function getInstance() {
    return Doctrine_Core::getTable('Amis');
  }
 
  static public function getAmis()
    {
        $dqlQuery = self::getInstance()
            ->createQuery('a')
            ->limit(1000);
         return $dqlQuery;
    }
}
Actions:
Code :
1
2
3
4
5
6
$query = AmisTable::getAmis();
$this->pager = new sfDoctrinePager('Amis', 10);
$currentPage = $request->getParameter('page', 1);
$this->pager->setPage($currentPage);
$this->pager->setQuery($query);
$this->pager->init();
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 12h16   #12
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
dans le sfDoctrinePager () tu as déclarer avec avoir une limit de 10, tu auras donc les 10 premier résultat en fonction de la page que tu as donné.

aucune des requête de doctrine te récupère les 5000 résultats.
Si tu ne veux pas tes 5000 résultats met des conditions.

Tu cherche a faire un truc impossible, car c'est tu demande une pagination donc tu as déjà un limit dans la requête qui est de 10 dans ton cas, un autre limit qui ne correspond à rien.

Je te conseil de lire comment fonctionne le limit en SQL.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 15h53   #13
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Franchement je suis perdu!

Avec ce code en haut ça m'affiche dans mon view une page avec 20 items.
Tout va bien jusque là. En bas la pagination: 1,2,3... 500 pages. Ce sont ces 500 pages que je ne veux pas avoir, je veux juste 100.
Et impossible de trouver une solution simple. Comment tu ferais toi? Obligé de passer par un subquery?
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 16h29   #14
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
ce que j'aimerai comprendre c'est pourquoi tu ne veux afficher que les 1000 premier ?
En faisant ça tu n'auras jamais les 4000 résultats suivant.

tu peux faire un sous select mais bon réfléchit bien a ce que je viens d'écrit avant, car la tu cherche à faire un fonctionnement anormale d'une base de données.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/01/2012, 09h14   #15
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Oui c'est exactement ce que je veux, juste les 1000 derniers. Les 4000 plus anciens ne me sont pas important pour mon application.

Passer par une subquery veut dire que le framework symfony n'a pas pensé à cette eventualité? Une subquery est toujours couteuse pour la performance.
Ya donc pas moyen de faire ça normalement avec symfony et doctrine?
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 09h59   #16
Futur Membre du Club
 
Inscription : août 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 24
Points : 18
Points : 18
Il faut avouer que tout besoin est tout sauf classique, en generale on fournit la possibilité d'accéder à tout les éléments car qui peut le plus peut le moins.

Quoiqu'il en soit, tu peux tout à fait réaliser ce que tu souhaite avec Symfo.
Il suffit simplement que lorsque tu affiches les liens de pagination, tu te limite à afficher un lien vers la Xe page de résultat et non vers le maximum.

Il faut voir le pager de Symfony comme un élément qui découpe automatiquement tes résultats de requête en autant de sous-page qu'il y a de " enregistrement / max_per_page ", il n'a rien a voir avec l'affichage des liens (qui est fait dans un template HTML).

Dans ton cas, la pagination t'afficherais 1,2,3,...500 suivant la logique classique, mais tu peux tout simplement ne plus afficher cela mais plutôt 1,2,3,...,100 ou encore 1,2,3,..50,...100 etc.. en modifiant le template de pagination.

Il n'y a à mon sens aucun interêt à limiter les résultats directement dans la query, ce que tu souhaites faire devrait typiquement passer par une surcharge de l'affichage qui n'affichera pas plus que la 100e page de résultats.
ufretin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 10h12   #17
Membre habitué
 
Inscription : juin 2006
Messages : 488
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 488
Points : 116
Points : 116
en reprenant ton besoin, tu as une table dans laquelle tu stock un "historique" mais dont tu ne veut "voir" que les 1000 derniers ?

pourquoi ne pas utiliser le comportement sofDelete. tu fait tourner un batch qui supprime virtuellement les data trop anciennes et tu ne travaille qu'avec les dernières valeurs ?
erictomcat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 10h28   #18
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 575
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2007
Messages : 575
Points : 690
Points : 690
Envoyer un message via MSN à kenny.kev
@ufretin : limité du coté requête permet de ne pas accéder au données si l'utilisateur les passe en paramètre.

@erictomcat : je suis tout a fait d'accord avec toi il a un problème de conception dans ça base de données.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 14h44   #19
Candidat au titre de Membre du Club
 
Inscription : novembre 2009
Messages : 41
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 41
Points : 10
Points : 10
Merci à tous pour vos efforts

Mon souci est au niveau de la performance, je ne souhaite donc rien effacer. Afficher les 5000 lignes alors que pas tous les utilisateurs en auraient besoin me semble pas nécessaire.

Ajouter un LIMIT aux dernières 1000 lignes seulement aiderait au niveau performance, non? Ou est-ce que ça ne changerait rien à l'affaire?
selecto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 15h18   #20
Membre habitué
 
Inscription : juin 2006
Messages : 488
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 488
Points : 116
Points : 116
heu rien compris la manque des mots
erictomcat est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h36.


 
 
 
 
Partenaires

Hébergement Web