2009-07-03 10 views
52

me gustaría preguntar cuál es la diferencia entresqlalchemy - Diferencia entre consulta y query.all en los bucles

for row in session.Query(Model1): 
    pass 

y

for row in session.Query(Model1).all(): 
    pass 

es la primera de alguna manera un iterador bombardeo de su base de datos con una sola consultas y este último "ansioso" consulta todo el asunto como una lista (como rango (x) vs xrange (x))?

Respuesta

73

No, no hay diferencia en el tráfico DB. La diferencia es que el primero hace que el ORM trabaje en cada fila cuando está por dárselo, mientras que el segundo hace que el ORM funcione en todas las filas, antes de comenzar a dárselos.

Tenga en cuenta que q.all() es solo azúcar para list(q), es decir, reúne todo lo que genera el generador en una lista. Aquí está el source code por ello, en la clase Query (Encontrar def all en el origen vinculado):

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) 

... donde self, el objeto de consulta, es un iterable, es decir, tiene un método __iter__.

Por lo tanto, lógicamente las dos formas son exactamente las mismas en términos de tráfico DB; ambos terminan llamando al query.__iter__() para obtener un iterador de fila, y next() abriéndose camino a través de él.

La diferencia práctica es que el anterior puede comenzar a darle filas tan pronto como sus datos hayan llegado, "transmitiendo" el resultado de DB establecido para usted, con menos uso de memoria y latencia. No puedo asegurar con certeza que todas las implementaciones actuales del motor hagan eso (¡espero que lo hagan!). En cualquier caso, esta última versión evita esa eficiencia, sin una buena razón.

+0

gracias, esta es una respuesta excelente – Tom

+9

[Esta publicación] (http://www.mail-archive.com/[email protected]/msg12443.html) arroja algo de luz sobre los detalles de implementación. Respuesta corta: '__iter__' * does * precapta todos los resultados (por una buena razón), pero este comportamiento se puede cambiar si sabes lo que estás haciendo. – Coquelicot

+0

Entonces, no hay ninguna ventaja al usar 'q.all()'? – dshgna

Cuestiones relacionadas