Entenda melhor os problemas do `yield_per ()` do SQLalchemy

CitarDocumentação SQLalchemy:

O método Query.yield_per () não é compatível com a maioria dos esquemas de carregamento ansiosos, incluindo subqueryload e joinload com coleções.

Aviso

Use este método com cuidado; se a mesma instância estiver presente em mais de um lote de linhas, as alterações do usuário final nos atributos serão substituídas.

Em particular, geralmente é impossível usar essa configuração com coleções carregadas avidamente (ou seja, qualquer preguiçoso = 'juntou-se' ou 'subconsulta'), pois essas coleções serão limpas para uma nova carga quando encontradas em um lote de resultados subsequente. No caso de carregamento de "subconsulta", o resultado completo de todas as linhas é buscado, o que geralmente anula o objetivo de yield_per ().

Observe também que, embora yield_per () defina a opção de execução stream_results como True, atualmente isso é entendido apenas pelo dialeto psycopg2, que transmite resultados usando cursores do lado do servidor em vez de pré-armazenar todas as linhas nesta consulta. Outros DBAPIs pré-protegem todas as linhas antes de disponibilizá-las. O uso de memória das linhas brutas do banco de dados é muito menor que o de um objeto mapeado pelo ORM, mas ainda deve ser levado em consideração ao fazer o benchmarking.

Eu realmente tenho um problema para entender comoyield_per() funciona e qual é exatamente o problema ao usar esse método. Além disso, qual é a maneira correta de solucionar esses problemas e continuar usando essa função para iterar uma enorme quantidade de linhas.

Estou interessado em todas as informações construtivas que você possui, mas aqui estão algumas dicas:

Como pode haver várias instâncias da mesma linha? Somente através de relacionamentos (se duas linhas da tabela de iteração tiverem um FK para a mesma linha em outra tabela)? Existe um problema se você não sabe o que acontece ou apenas lê atributos nos relacionamentos?preguiçoso = 'ingressou' ou 'subconsulta' não é possível, mas por que exatamente? Ambos são simplesmente partes da sua consulta à qual você chamayield_per().Se eles forem limpos em um lote de resultados subsequente, basta carregá-lo novamente. Então onde está o problema? Ou é o único problema que você perde as mudanças de seus relacionamentos se elas fizeram mudanças?No caso de um carregamento de "subconsulta", por que todas as linhas são buscadas? O SQL Server pode precisar salvar uma tabela grande, mas por que não simplesmente retornar o resultado em lotes, um após o outro, para toda a consulta?Em um exemplo noyield_per() doc q = sess.query(Object).yield_per(100).options(lazyload('*'), joinedload(Object.some_related)) eles desativam o ealoadload comlazyload('*') mas mantenha uma única carga unida. Existe uma maneira de ainda usaryield_per() com ansioso? Quais são as condições?Eles dizempsycopg2 é o único DBAPI que suporta resultados de fluxo. Assim é que o único DBAPI com o qual você pode usaryield_per()? Tanto quanto eu entendoyield_per usa ocursor.fetchmany() (exemplo) função do DBAPI que suporta muitos deles. E até onde eu entendocursor.fetchmany() suporta buscar apenas partes do resultado e não buscar tudo (se buscaria tudo, por que a função existe?)Eu tenho a sensação de queyield_per() é totalmente seguro (mesmo com carga rápida) se você apenas tiver acesso de leitura (por exemplo, para estatísticas). Isso está correto?

questionAnswers(1)

yourAnswerToTheQuestion