Requête Flask SQLAlchemy, spécifiez les noms de colonne


126

Comment spécifier la colonne que je souhaite dans ma requête à l'aide d'un modèle (il sélectionne toutes les colonnes par défaut)? Je sais comment faire cela avec la session sqlalchmey:, session.query(self.col1)mais comment puis-je le faire avec des modèles? Je ne peux pas faire SomeModel.query(). Y a-t-il un moyen?

Réponses:


221

Vous pouvez utiliser la with_entities()méthode pour restreindre les colonnes que vous souhaitez renvoyer dans le résultat. ( documentation )

result = SomeModel.query.with_entities(SomeModel.col1, SomeModel.col2)

En fonction de vos besoins, vous trouverez peut-être également utile les reports. Ils vous permettent de renvoyer l'objet complet mais limitent les colonnes qui passent sur le fil.


21
with_entities () fait que all () donne des tuples de valeurs de colonne, pas d'objets!
kolypto

10
kolypto: Il donne tout ce que vous lui demandez de céder. SomeModel.query.with_entities (SomeModel) donnerait l'objet. Tout comme session.query (SomeModel.col1, SomeModel.col2) produirait des tuples de valeurs de colonne. Les différés sont ce que vous utiliseriez si vous ne voulez pas que les colonnes passent sur le fil, mais que vous voulez quand même l'objet entier.
David McKeone

2
Merci ça marche. Mais comment pourrions-nous attribuer un alias au champ? Parce que dans mon cas, j'utilise JOIN et le IDchamp de conflit qui est présent dans les deux tableaux
Mitul Shah

Ouais, j'ai la même question avec @MitulShah, comment définir un alias?
Nam G VU

Pour l'alias, consultez cette brève réponse ci-dessous, c'est-à-dire. utilisez .label() stackoverflow.com/a/11535992/248616
Nam G VU

69
session.query().with_entities(SomeModel.col1)

est le même que

session.query(SomeModel.col1)

pour alias, nous pouvons utiliser .label ()

session.query(SomeModel.col1.label('some alias name'))

2
Le second semble à la fois plus logique et plus court - gagnant / gagnant
fgblomqvist

7
Votre première déclaration est fausse. Vous avez besoin de parenthèses. Donc, il devrait lire:session.query().with_entities(SomeModel.col1)
JGFMK

Les première (et troisième) options sont de loin les meilleures si vous souhaitez réutiliser des objets de requête existants, en particulier dans le cas de l'exécution de plusieurs sous-requêtes complexes.
Jamie Strauss

36

Vous pouvez utiliser la fonction load_only :

from sqlalchemy.orm import load_only

fields = ['name', 'addr', 'phone', 'url']
companies = session.query(SomeModel).options(load_only(*fields)).all()

1
Cette solution est la meilleure car elle fonctionne toujours en tant qu'objet et non seulement en tant que liste de résultats.
rborodinov le

Bravo à vous pour cette solution. Il présente de nombreux avantages: - retourne exactement le même type d'objet que .first()et .one()(qui chargera les champs et les relations paresseux / impatients), - peut être défini comme composant de requête
Damien le

le code est propre mais la requête sql sélectionne tous les champs de la base de données. J'ai utilisé with_entitiescomme indiqué dans la réponse acceptée et la requête n'a sélectionné que les champs /.
Srikanth Jeeva

11

Vous pouvez utiliser Model.query, car le Model(ou généralement sa classe de base, en particulier dans les cas où l'extension déclarative est utilisée) est affecté Sesssion.query_property. Dans ce cas, le Model.queryéquivaut à Session.query(Model).

Je ne connais pas la manière de modifier les colonnes retournées par la requête (sauf en ajoutant plus à l'aide add_columns()).
Donc, votre meilleur coup est d'utiliser le Session.query(Model.col1, Model.col2, ...)(comme déjà montré par Salil).


Je crois qu'il peut également y avoir un moyen de le faire avec une liste de colonnes pour les valeurs de requête () aussi, docs.sqlalchemy.org/en/latest/orm / ... - mais le sucre syntaxique pour la liste m'échappe pour le moment.
JGFMK


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.