No, non c'è differenza nel traffico DB. La differenza è che il primo fa funzionare l'ORM su ogni riga quando sta per dartelo, mentre il secondo fa funzionare l'ORM su tutte le righe, prima di iniziare a dartelo.
Si noti che q.all()
è solo zucchero per list(q)
, vale a dire la raccolta di tutto il rendimento dal generatore in una lista. Ecco il source code per esso, nella classe Query
(trovare def all
in origine collegata):
def all(self):
"""Return the results represented by this ``Query`` as a list.
This results in an execution of the underlying query.
"""
return list(self)
... dove self
, l'oggetto query, è un iterabile, cioè ha un metodo __iter__
.
Quindi logicamente i due modi sono esattamente gli stessi in termini di traffico DB; entrambi finiscono per chiamare query.__iter__()
per ottenere un iteratore di riga e next()
attraverso di esso.
La differenza pratica è che il precedente può iniziare a fornire le righe non appena i loro dati sono arrivati, "streaming" del risultato del DB impostato, con meno utilizzo della memoria e latenza. Non posso affermare con certezza che tutte le attuali implementazioni del motore lo facciano (spero lo facciano!). In ogni caso quest'ultima versione impedisce tale efficienza, senza una buona ragione.
fonte
2009-07-03 17:01:02
grazie, questa è una risposta eccellente – Tom
[questo post] (http://www.mail-archive.com/[email protected]/msg12443.html) fa luce sui dettagli di implementazione. Risposta breve: '__iter__' * fa * preleva tutti i risultati (per una buona ragione), ma questo comportamento può essere cambiato se sai cosa stai facendo. – Coquelicot
Quindi non c'è alcun vantaggio nell'usare 'q.all()'? – dshgna