SQLAlchemy: solo se devuelve un resultado cuando count () dice que hay más

Estoy teniendo problemas con un gran conjunto de resultados que solo devuelve una fila.

Session.query(TestSet).join(Instance).count() >> 4283878 Session.query(TestSet).join(Instance).offset(0).limit(100).count() >> 100 Session.query(TestSet).join(Instance).offset(0).limit(100).all() >> [] 

Es decir, all devuelve solo una instancia de mi modelo, en lugar de 100. Ahora, para algo aún más extraño:

 len(Session.query(TestSet).join(Instance).offset(0).limit(100).distinct().all()) >> 100 

Así que si agrego distinct antes de all , recupero los 100 resultados. ¿Que está pasando aqui?

Related of "SQLAlchemy: solo se devuelve un resultado cuando count () dice que hay más"

El objeto Query , cuando se le pide que itere a través de los resultados que representan una entidad como TestSet , se realiza uniquing en las filas de resultados basándose en la identidad del objeto, de modo que si la consulta devolviera 100 filas cada una con la misma clave principal de TestSet , solo obtendría un resultado resultado de nuevo. Este comportamiento tiene sus orígenes en la función de “unión ansiosa” de Query , donde a menudo se reciben muchas filas de resultados, cada una con la misma identidad primaria, pero que también contiene una identidad secundaria variable de una fila relacionada con la que se debe rellenar una colección sobre cada identidad primaria; solo una instancia de la identidad primaria es deseable en este caso muy común.

Consideremos entonces lo que distinct() hace. Supongamos que su consulta para objetos 4M devuelve 1000 filas con id = 1, 1000 filas con id = 2, etc. La consulta con límite (100) llega a las primeras 100 filas con id = 1, Query unifica, y obtiene un objeto resultante de nuevo , ya que todos son id = 1. Pero con distinct() , de repente obtenemos 100 filas con identidades distintas, es decir, “id = 1”, “id = 2”, “id = 3”. Luego, Query asigna cada una de estas filas a un nuevo objeto TestSet en el mapa de identidad, y obtiene 100 filas atrás.

Al establecer echo='debug' en su Engine temporalmente, se mostrará el SQL que se está emitiendo y las filas de resultados que regresan. Cuando ve muchas filas de resultados con la misma clave principal, sabe que cuando se le pide que devuelva entidades completas, todas esas identidades redundantes serán únicas hasta el único objeto representado para cada fila.