9
votes

Comment paginer dans le flacon-sqlalchemy for dB.Session a rejoint les requêtes?

Dites, nous avons les relations suivantes:

  • Une personne peut avoir de nombreuses adresses électroniques li>
  • Un fournisseur de services de messagerie peut (évidemment) servir plusieurs adresses électroniques li> ul>

    Donc, c'est beaucoup à de nombreuses relations. J'ai trois tables: courriels, prestataires et utilisateurs. Les courriels ont deux identifiants étrangers pour le fournisseur et l'utilisateur. P>

    Maintenant, compte tenu d'une personne spécifique, je souhaite imprimer tous les fournisseurs de messagerie et l'adresse e-mail qu'elle accueille pour cette personne, s'il existe. (Si la personne n'a pas de courrier électronique à Gmail, je veux toujours que Gmail soit dans le résultat. Je pense que, autrement, j'ai seulement besoin d'une jointure intérieure gauche pour résoudre ceci.) P>

    J'ai compris comment faire ça Avec les sous-candidats suivants (suivant le tutoriel SQLalchemy): P>

    email_subq = db.session.query(Emails).\
                    filter(Emails.user_id==current_user.id).\
                    subquery()
    
    provider_and_email = db.session.query(Provider, email_subq).\
                    outerjoin(email_subq, Provider.emails).\
                    all()
    


0 commentaires

7 Réponses :


-1
votes

Je pourrais avoir tort, mais je pense que votre problème peut être le fichier .all (). En utilisant cela, vous obtenez une liste, pas un objet de requête.

Essayez de le quitter et transmettez votre requête à la méthode de la pagination comme si (j'ai laissé tous les détails de la sous-requête pour la clarté de la clarté): P>

email_query = db.session.query(Emails).filter(**filters)
email_query.paginate(page, per_page)


4 commentaires

J'ai remplacé le tout () avec paginate () et approprié argument à celui-ci, donc je appelle paginate sur un sqlalchemy.orm.orm.Query Objet .Query (vérifié dans la page d'erreur de la fiole de débogueur). Je suppose que ce n'est pas la source d'erreur ici. Désolé de ne pas être clair dans la question.


Dang, j'avais espéré que c'était quelque chose de facile. Que se passe-t-il si vous utilisez le flacon-sqlalchemy Requête Alias? Quelque chose comme ceci: email.query.filter (emails.user_id == actuel_user.id) .Orterjoi n (fournisseur de fournisseur, fournisseuremail.provider_id == email.Id)


Il produit une requête SELECT avec uniquement les champs de e-mail inclus, de sorte que rien sur le fournisseur n'est renvoyé; Au moins, c'est le cas la dernière fois que j'ai essayé.


paginate ne fonctionne pas avec db.session.Query (table) .Filter (** condition) .paginate () . Ce ne fonctionne que si nous appelons la classe de modèle comme table.Query.filter (** condition) .paginate () . Cette réponse est incorrecte.



0
votes

Comment allez-vous votre application avec SQLALCHEMY?

Probablement votre connexion SQLalchemy actuelle n'a rien à voir avec le flacon.ext.sqalchemy et vous utilisez l'original SQLALCHEMY

Vérifiez ce tutoriel et vérifiez vos importations, qu'ils viennent vraiment de flask.ext.sqlalchemy

http://pythonhosted.org/flask-sqlalchemy/QuickStart. HTML # A-Minimal-Application


1 commentaires

Je suis presque sûr que j'ai initié le flacon-Sqlalchemy la bonne façon. Tous les modes .Quisery fonctionnent correctement pour moi. Et j'ai effectivement suivi le tutoriel ci-dessus.



12
votes

Je ne sais pas si cela va finir par être la solution à long terme et que cela ne concerne pas directement que je m'inquiète de ne pas utiliser la baseQuery de Flack-Sqlalchemy, mais le moyen le plus trivial pour accomplir ce que je veux est de réimplément la fonction de paginate.

et, en fait, il est assez facile d'utiliser la routine originale du flacon-sqlalchemy pour le faire: xxx

modifié de la < Code> Paginate Fonction trouvée autour de la ligne 376: https://github.com/mitsuhiko /flask-sqlalchemy/blob/master/flask_sqlalchemy.py


2 commentaires

Avez-vous essayé de voir si la requête que vous avez construite pourrait être utilisée pour créer un nouvel objet de basequery (similaire à la manière dont vous créez un objet de paginate) vous permettant de réutiliser la fonction de paginate de basequery?


Ah oui. Je suppose que je pourrais, mais je n'ai pas encore essayé. Merci de le pointer.



3
votes

Hey j'ai trouvé une solution rapide pour cela ici c'est:

provider_and_email = Provider.query.with_entities(email_subq).\
            outerjoin(email_subq, Provider.emails).paginate(page, POST_PER_PAGE_LONG, False)


0 commentaires

4
votes

Votre question est de savoir comment utiliser la pagination de Flack-Sqlalchemy avec des requêtes sqlalchemy régulières.

Étant donné que l'objet de basequery de Flack-Sqlalchemy ne contient aucun état de son propre, et est dérivé de la requête de Sqlalchemy et est vraiment un conteneur pour des méthodes, Vous pouvez utiliser ce piratage: xxx

à utiliser: xxx

* EDIT:

s'il vous plaît Soyez prudent de faire cela. C'est vraiment un moyen d'éviter de copier / coller la fonction paginate , comme on le voit dans l'autre réponse. Notez que la baseQuery n'a pas de __ init __ méthode. Voir Quelle est la dangereuse de paramètres auto .__ Classe __ à quelque chose d'autre? .

* EDIT2:

Si baseQuery avait un __ init __ , vous pouvez construire une utilisation de l'objet de requête SA, Plutôt que de pirater .__ classe __ .


1 commentaires

Je reçois Sa_Query .__ CLASS__ = BASSEQUERY TYPEERROR: Classe Affectation: uniquement pour les types de tas '



3
votes

Je suis actuellement en train d'utiliser cette approche: xxx pré>

pour créer mon propre basequery code>. db code> est l'instance sqlalchemy code>. p>

mise à jour: comme @ Afilbert suggère Vous pouvez également faire ceci: p>

query = BaseQuery(provider_and_email.subquery(), db.session())


2 commentaires

Il vous apparaît également que vous pouvez également prendre n'importe quel objet de requête SQLALCHEMY et appelez simplement la méthode .SubQuery (). Ainsi, en utilisant l'exemple de l'OP: Query_with_pagination = basequery (fournisseur_and_email.subquery (), dB.session ()) Le vôtre devrait être la réponse acceptée, imo.


@afilbert Les autres ont été postés dans '13, a ajouté la mienne parce que je l'ai mieux aimé. Merci pour le soutien moral cependant; )



0
votes

Vous pouvez essayer de paginer la liste avec des résultats. xxx


0 commentaires