sqlalchemy, en tournant une liste d'Id d'une liste d'objets
J'ai séquence d'Id je veux récupérer. C'est simple:
session.query(Record).filter(Record.id.in_(seq)).all()
Est-il un meilleur moyen de le faire?
- Ce que vous n'aimez pas ça? N'est-il pas de travail? Il semble comme il se doit.
- Il travaille, que je me demandais s'il y avait de mieux à faire.
- Qu'entendez-vous par "plus agréable"? Ce que vous n'aimez pas ce que c'est?
- Méfiez-vous que si
seq
obtient assez longtemps, vous pouvez obtenir un "trop grand nombre de variables SQL' exception parce que la clause est paramétrable et il y a trop de paramètres.
Vous devez vous connecter pour publier un commentaire.
Votre code est absolutety amende.
IN
est comme un tas deX=Y
rejoint avecOR
et assez rapide dans contemporain des bases de données.Toutefois, si votre liste d'Id est longue, vous pourriez faire la requête un peu plus efficace par le passage d'une sous-requête qui renvoie la liste des Identifiants.
Le code est tout à fait acceptable. Cependant, quelqu'un me demande un système de couverture entre les deux approches, de faire un grand DANS contre l'utilisation de get() pour chaque Id.
Si quelqu'un est vraiment en essayant d'éviter le SÉLECTIONNER, puis la meilleure façon de le faire est de configurer les objets dont vous avez besoin dans la mémoire à l'avance. Tels que, vous travaillez sur un grand tableau d'éléments. Briser le travail en morceaux, tels que, afin de l'ensemble des travaux par clé primaire, ou par plage de date, que ce soit, alors la charge de tout pour que le morceau localement en cache:
C'est le monde réel de cas d'utilisation.
Mais aussi d'illustrer certains de SQLAlchemy API, nous pouvons faire une fonction qui fait le DANS les pour les registres, nous n'avons pas et un local à obtenir pour ceux que nous ne. Ici, c'est que:
Voici une démonstration:
Si vous utilisez les clés primaires composites, vous pouvez utiliser
tuple_
, comme dansNoter que ce n'est pas disponible sur SQLite (voir doc).
Je vous recommande de prendre un regard sur SQL qu'il produit. Vous pouvez simplement imprimer str(requête) pour le voir.
Je ne suis pas au courant de la façon idéale de le faire avec le standard SQL.
Il existe une autre façon; S'il est raisonnable de s'attendre à ce que les objets en question sont déjà chargés dans la session; vous avez consulté avant dans la même transaction, vous pouvez faire au lieu de:
Dans le cas où ces objets sont déjà présents, ce sera beaucoup plus rapide, car il n'y aura pas des requêtes pour récupérer ces objets; d'autre part, si plus qu'un petit nombre de ces objets sont pas chargé, il sera beaucoup, beaucoup plus lent, car il sera la cause d'une requête par l'manquant exemple, au lieu d'une seule requête pour tous les objets.
Cela peut être utile lorsque vous faites
joinedload()
requêtes avant d'atteindre l'étape ci-dessus, de sorte que vous pouvez être sûr qu'ils ont été déjà chargé. En général, vous devez utiliser la solution de la question par défaut, et seulement explorer cette solution quand vous avez vu que vous interrogez pour les mêmes objets et plus.