Comprender mejor los problemas de SQLalchemy `yield_per ()`

CitarDocumentación de SQLalchemy:

El método Query.yield_per () no es compatible con la mayoría de los esquemas de carga ansiosos, incluidas la subconsulta y la carga conjunta con colecciones.

Advertencia

Use este método con precaución; Si la misma instancia está presente en más de un lote de filas, los cambios de los usuarios finales a los atributos se sobrescribirán.

En particular, generalmente es imposible usar esta configuración con colecciones cargadas con entusiasmo (es decir, cualquier perezoso = 'unido' o 'subconsulta'), ya que esas colecciones se borrarán para una nueva carga cuando se encuentren en un lote de resultados posterior. En el caso de la carga de "subconsulta", se obtiene el resultado completo de todas las filas, lo que generalmente anula el propósito de yield_per ().

También tenga en cuenta que mientras yield_per () establecerá la opción de ejecución stream_results en True, actualmente esto solo se entiende por el dialecto psycopg2 que transmitirá los resultados utilizando cursores del lado del servidor en lugar de almacenar previamente todas las filas para esta consulta. Otros DBAPI almacenan previamente todas las filas antes de ponerlas a disposición. El uso de la memoria de las filas de la base de datos sin procesar es mucho menor que el de un objeto mapeado por ORM, pero aún debe tenerse en cuenta al realizar una evaluación comparativa.

Realmente tengo un problema para entender cómoyield_per() funciona y cuál es exactamente el problema al usar este método. Además, ¿cuál es la forma correcta de solucionar estos problemas y seguir utilizando esta función para iterar en una gran cantidad de filas?

Estoy interesado en toda la información constructiva que tenga, pero aquí hay algunas preguntas indirectas:

¿Cómo puede haber varias instancias de la misma fila? ¿Solo a través de relaciones (si dos filas de la tabla iterativa tienen un FK a la misma fila en otra tabla)? ¿Hay algún problema si no sabes que sucede o si solo lees atributos en las relaciones?lazy = "unidos" o "subconsulta" no son posibles, pero ¿por qué exactamente? Ambos son simplemente partes de su consulta a las que llamayield_per().Si se borran en un lote de resultados posterior, simplemente cárguelo nuevamente. ¿Entonces, dónde está el problema? ¿O es el único problema que pierde los cambios de sus relaciones si ha realizado cambios?En el caso de una carga de "subconsulta", ¿por qué se obtienen todas las filas? Es posible que SQL Server tenga que guardar una tabla grande, pero ¿por qué no simplemente devolver el resultado en lotes uno tras otro para toda la consulta?En un ejemplo en elyield_per() Doc q = sess.query(Object).yield_per(100).options(lazyload('*'), joinedload(Object.some_related)) desactivan eagerload conlazyload('*') pero mantenga una sola carga unida. ¿Hay alguna manera de seguir usandoyield_per() con eagerload? ¿Cuales son las condiciones?Ellos dicenpsycopg2 es el único DBAPI que admite resultados de flujo. Entonces, ese es el único DBAPI que puedes usar conyield_per()? Hasta donde yo entiendoyield_per usa elcursor.fetchmany() (ejemplo) función de DBAPI que soporta muchos de ellos. Y hasta donde yo entiendocursor.fetchmany() admite la recuperación de solo partes del resultado y no recupera todo (si fuera a recuperar todo, ¿por qué existe la función?)Tengo la sensación de queyield_per() es completamente seguro (incluso con eagerload) si solo tiene acceso de lectura (por ejemplo, para estadísticas). ¿Es eso correcto?

Respuestas a la pregunta(1)

Su respuesta a la pregunta