Como transformar a função abaixo numa única query?

14 views
Skip to first unread message

Murilo Scarpa

unread,
Mar 27, 2021, 7:01:31 PMMar 27
to Django Brasil
Boa tarde, pessoal.

Preciso obter apenas a versão final de um modelo previamente distinto por um campo não nulo. Fiz a mesma pergunta no stack overflow e acho que lá é mais fácil de explicar: https://stackoverflow.com/questions/66822150/how-to-get-the-latest-version-of-a-all-previously-distinctable-objects-within-a

Estou usando PostegreSQL.

Obrigado!

Marcos Thomaz

unread,
Mar 27, 2021, 7:13:14 PMMar 27
to django...@googlegroups.com
Seria isso? list = Workflow.objects.filter(enabled=True).values('process_id').aggregate(max_version=Max('version'))

--
Você recebeu essa mensagem porque está inscrito no grupo "Django Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para django-brasi...@googlegroups.com.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/django-brasil/4646824f-dea3-4e91-9d83-bf56da55e528n%40googlegroups.com.


--


Marcos Thomaz da Silva
Analista de Tecnologia da Informação

Murilo Scarpa

unread,
Apr 1, 2021, 5:34:13 PMApr 1
to django...@googlegroups.com
Não, Marcos.

A sua query retorna a versão mais recente de TODOS os Workflows. Como comentei lá na pergunta chegaríamos próxima da resposta de substituíssemos aggregate por annotate, mas ainda assim não todas as colunas da tabela.

A solução é usar uma Subquery em conjunto com OuterRef: 

def get_only_latest_versions(selfqueryset_value):
    if value:
        subquery = queryset.filter(engine_bpmn_process_id=OuterRef(
            'engine_bpmn_process_id'), enabled=True).order_by('-version')
        return queryset.filter(version=Subquery(subquery.values('version')[:1]))
    return queryset

Marcos Thomaz

unread,
Apr 2, 2021, 12:23:25 AMApr 2
to django...@googlegroups.com
Oi Murilo, acho que não entendi direito então. Veja, no stackoverflow você colocou o seguinte: "I'm trying to find the latest version for each process_id within a single query. "

Quando faço assim:  list = Workflow.objects.filter(enabled=True).values('process_id').aggregate(max_version=Max('version'))

Seria equivalente a: select process_id, max(version) as max_version from workflow group by process_id
Ou seja, pegaria a última versão de cada process_id. Ou não era isso que você queria?




Marcos Thomaz

unread,
Apr 2, 2021, 1:01:15 AMApr 2
to django...@googlegroups.com
Desculpa Murilo, cometi um erro e insisti nele sem ler direito... o problema ali é com os demais campos. A resposta de lá atende (vai apenas 1 vez ao banco de dados, sendo a consulta retornada por "subquery" usada dentro de um único SQL. Algo do tipo:
select * from workflow where version = (select w2.version from workflow w2 where w2.process_id=workflow.process_id and w2.enabled=true order by w2.version desc limit 1)
Reply all
Reply to author
Forward
0 new messages