Reduzir consultas e conexões ao banco de dados#1410
Reduzir consultas e conexões ao banco de dados#1410robertatakenaka merged 26 commits intoscieloorg:mainfrom
Conversation
…s de ambiente - CELERY_TASK_TIME_LIMIT: hard limit configurável via env (default 36000s) - CELERY_TASK_SOFT_TIME_LIMIT: soft limit configurável via env (default 3600s) - Adiciona CELERY_WORKER_MAX_TASKS_PER_CHILD para reciclagem de workers (default 100) - Adiciona CELERY_WORKER_CONCURRENCY configurável via env (default 4) - Comenta CELERY_RESULT_BACKEND='django-db'; resultado já persiste via Redis
- Simplifica CONN_MAX_AGE para 60s fixo via env (remove variável duplicada) - Remove POOL_OPTIONS (incompatível com django-prometheus backend) - Migra SESSION_ENGINE para cache Redis (SESSION_ENGINE + SESSION_CACHE_ALIAS) - Reduz escritas no PostgreSQL a cada request com SESSION_SAVE_EVERY_REQUEST=True
…ponível - Prioriza request.user.is_authenticated antes de consultar o banco - Fallback para user_id e username quando request não tem usuário autenticado - Remove acesso incorreto a request.user_id (AttributeError silencioso anterior)
- Atribui request.user.collection.all() a variável local antes de reutilizar - Elimina segunda query duplicada para set_current_collections e request.user_collection
- Evita N+1 queries ao listar licenças no admin Wagtail
…alores antes de persistir - State.create_or_update: salva apenas se name ou acronym mudaram - CountryName.create_or_update: salva apenas se country, language ou text mudaram - Country.create_or_update: salva apenas se name, acronym ou acron3 mudaram - CountryName.get_country: substitui loop por .filter(country__isnull=False).select_related().first()
- User.objects.get(id=user_id) executado uma única vez antes de iterar o CSV - Elimina N queries redundantes ao banco durante importação em massa
- Inclui country, state, city e creator para evitar N+1 no admin Wagtail
…o valores antes de persistir - Institution.create_or_update: salva apenas se institution_type ou url mudaram - InstitutionIdentification.create_or_update: salva apenas se is_official ou official mudaram - Garante que updated_by só é gravado quando há mudança efetiva
…nsolidar saves - update_logo e update_url retornam True/False sem chamar save() internamente - create_or_update chama save() uma única vez se logo ou url mudaram - update_institutions retorna bool; create_or_update chama save() apenas se houve mudança - Organization.update_institutions remove save() interno; responsabilidade delegada ao chamador
…__official em task de migração - Evita query extra ao acessar official durante migração de Institution para Organization
…em JournalHistory
- OfficialJournal.add_old_title/add_new_title: substitui loop por .filter().first()
- add_old_title: remove self.save() após M2M .add() (desnecessário)
- add_new_title: remove self.save(); responsabilidade delegada ao chamador
- Journal.collection_acrons: substitui loop por values_list com select_related
- Journal.get_ids / get_legacy_keys: adiciona select_related('collection') nos filtros
- JournalHistory.load: substitui get/except+save duplo por update_or_create para ADMITTED e INTERRUPTED
…de IssueAdminSnippetViewSet - Evita N+1 queries ao listar issues no admin Wagtail
…orcid e lattes - Elimina iteração desnecessária; retorna diretamente o primeiro identifier encontrado - Remove acesso ao atributo do objeto relacionado; usa projeção via values_list
…gração
- Adiciona select_related('affiliation__institution__location')
- Adiciona prefetch_related('researcheraka_set__researcher_identifier')
- Reduz queries N+1 ao acessar location e identifiers durante migração
…ueries extras
- XMLVersion.get_or_create: documenta fluxo de 3 saves (pk → arquivo → consolidação)
- PidProviderXML.public_items: adiciona select_related('current_version')
- PidProviderXML._add_current_version: remove save() interno; delegado ao chamador
- PidProviderXML._add_other_pid: remove save() interno; delegado ao chamador
- PidProviderXML._save: adiciona save() consolidado após _add_current_version/_add_other_pid
- best_matches: adiciona select_related('current_version') no iterator
- Elimina duplicação de _get_user em pid_provider/tasks.py - Importa _get_user centralizado de core.utils.utils
- Elimina definição local de _get_user em tracker/tasks.py - Função centralizada já disponível em core.utils.utils
- Elimina definição local de _get_user - Atualiza chamadas para assinatura _get_user(request=None, user_id=..., username=...) - Importa _get_user centralizado de core.utils.utils
…_collections - Substitui if/if por if/elif para evitar reatribuição silenciosa de user - Levanta ValueError explícito quando nem user_id nem username são fornecidos
…e_ebm - Atribui request.user a user antes do loop para evitar acesso repetido ao objeto request - Padroniza uso de user nas chamadas a create_or_update dentro do loop
…SnippetViewSets - GenericThematicAreaAdmin, GenericThematicAreaFileAdmin - ThematicAreaAdmin, ThematicAreaFileAdmin - Evita N+1 queries ao listar registros no admin Wagtail
…to_articlemeta - Inclui journal, journal__official e pp_xml para evitar N+1 durante exportação em massa
There was a problem hiding this comment.
Pull request overview
Este PR reúne otimizações para reduzir volume de queries e writes no PostgreSQL (principalmente em listagens do Wagtail admin e em tasks Celery), além de ajustes de settings de produção para diminuir a pressão de conexões e mover sessões para Redis.
Changes:
- Otimiza querysets (principalmente via
select_related/prefetch_related) em múltiplos SnippetViewSets, models e tasks para eliminar N+1. - Reduz saves/updates desnecessários (flags de “changed”, consolidação de saves e refactors para evitar
save()interno). - Ajusta settings operacionais (CONN_MAX_AGE/health checks, sessão via cache/Redis, parâmetros Celery) e consolida
_get_user()emcore.utils.utils.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tracker/tasks.py | Remove helper _get_user duplicado (não utilizado no arquivo). |
| thematic_areas/wagtail_hooks.py | Adiciona select_related("creator") nos querysets do admin para reduzir N+1. |
| researcher/tasks.py | Adiciona select_related/prefetch_related para reduzir queries na migração. |
| researcher/models.py | Otimiza orcid/lattes com values_list(...).first() evitando loops. |
| pid_provider/tasks.py | Importa _get_user centralizado em vez de função local duplicada. |
| pid_provider/models.py | Consolida saves e adiciona select_related("current_version") para reduzir N+1 (há pontos com save redundante). |
| organization/tasks.py | Expande select_related para evitar queries adicionais em migração. |
| organization/models.py | Evita saves internos; refatora helpers para retornarem “changed” e salvar apenas uma vez. |
| location/wagtail_hooks.py | Adiciona select_related no admin de Location para evitar N+1 em FKs. |
| location/scripts/bulk_cities.py | Move lookup de usuário para fora do loop para evitar N queries. |
| location/models.py | Evita save() quando não há mudança real; otimiza get_country com .first(). |
| journal/models.py | Troca loops por .first(), otimiza acesso a coleções e usa update_or_create em histórico. |
| issue/wagtail_hooks.py | Inclui creator/updated_by em select_related para reduzir N+1 no admin. |
| institution/models.py | Evita save() quando não há mudança real em create_or_update. |
| editorialboard/views.py | Evita acessos repetidos a request.user dentro do loop de importação. |
| core/wagtail_hooks.py | Otimiza admin de License com select_related("creator"). |
| core/utils/utils.py | Atualiza _get_user para priorizar request.user autenticado antes de buscar no banco. |
| core/middleware.py | Reutiliza o mesmo queryset de coleções do usuário no middleware (evita re-fetch). |
| config/settings/production.py | Ajusta CONN_MAX_AGE/health checks, remove POOL_OPTIONS e move sessões para cache/Redis. |
| config/settings/base.py | Ajusta time limits do Celery e configurações de reciclagem/concurrency; evita “django-db” como backend de results. |
| collection/tasks.py | Corrige fluxo user_id vs username e adiciona erro explícito quando nenhum é fornecido. |
| bigbang/tasks.py | Passa a usar _get_user centralizado com a nova assinatura. |
| article/controller.py | Adiciona select_related no iterator do bulk export para reduzir queries por artigo. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| obj.save_file( | ||
| f"{pid_provider_xml.v3}.xml", xml_with_pre.tostring(pretty_print=True) | ||
| ) | ||
| # Único save final após salvar o arquivo | ||
| obj.save() |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Este PR aplica otimizações transversais para reduzir consultas ao PostgreSQL (especialmente N+1 em admin/tasks), evitar save()/UPDATE desnecessários e ajustar configurações de produção para diminuir pressão de conexão e writes no banco.
Changes:
- Adiciona
select_related/values_list(...).first()/update_or_createem pontos quentes (admin Wagtail, tasks e models) para reduzir N+1 e queries pontuais. - Refatora métodos
create_or_update/helpers para só persistirem quando houver mudança real, consolidando saves no chamador. - Ajusta settings (produção e base) para reduzir pressão no PostgreSQL (CONN_MAX_AGE, sessões em cache/Redis, backend de resultado Celery) e consolida
_get_useremcore.utils.utils.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tracker/tasks.py | Remove helper _get_user duplicado em tasks do app tracker. |
| thematic_areas/wagtail_hooks.py | Otimiza queryset do admin Wagtail com select_related("creator"). |
| researcher/tasks.py | Otimiza queryset da migração de pesquisadores com select_related/prefetch_related. |
| researcher/models.py | Troca loop por values_list(...).first() em properties (orcid/lattes). |
| pid_provider/tasks.py | Consolida uso de _get_user via import único de core.utils.utils. |
| pid_provider/models.py | Reduz N+1 com select_related e consolida persistência/saves em _save e versões XML. |
| organization/tasks.py | Aumenta select_related em task de migração para evitar N+1 em FK encadeada. |
| organization/models.py | Elimina saves internos em helpers e retorna flags para consolidar persistência no chamador. |
| location/wagtail_hooks.py | Otimiza listagem do admin Wagtail de Location com select_related. |
| location/scripts/bulk_cities.py | Move lookup de User para fora do loop para evitar queries repetidas. |
| location/models.py | Evita save() quando não há mudança e reduz query em CountryName.get_country. |
| journal/models.py | Reduz queries em títulos/coleções e troca get+except+save por update_or_create. |
| issue/wagtail_hooks.py | Otimiza queryset do admin Wagtail de Issue com select_related (creator/updated_by). |
| institution/models.py | Evita save() quando não há mudança em create_or_update. |
| editorialboard/views.py | Evita acesso repetido a request.user dentro do loop de importação. |
| core/wagtail_hooks.py | Otimiza queryset do admin Wagtail de License com select_related("creator"). |
| core/utils/utils.py | Corrige e padroniza _get_user (prioriza request.user autenticado). |
| core/middleware.py | Reusa queryset de coleções do usuário para evitar chamadas duplicadas. |
| config/settings/production.py | Ajusta conexões persistentes, remove pooling e move sessões para cache/Redis em produção. |
| config/settings/base.py | Ajusta limites/config do Celery (time limits, reciclagem e concorrência) e mantém result backend em Redis. |
| collection/tasks.py | Corrige lógica de seleção de usuário (if/elif/else) e adiciona erro explícito quando ausente. |
| bigbang/tasks.py | Consolida _get_user via util compartilhado. |
| article/controller.py | Otimiza export em massa com select_related antes do .iterator(). |
Comments suppressed due to low confidence (1)
researcher/tasks.py:33
prefetch_related("researcheraka_set__researcher_identifier")não evita as queries dentro do loop porque o código usaold_researcher.researcheraka_set.filter(...).first(), e.filter()não usa o cache do prefetch (tende a executar uma query por researcher). Para realmente eliminar o N+1, ou remova este prefetch, ou refatore para consumir o conjunto prefetched em memória (ex.: iterar/next(...)) ou usePrefetch(..., to_attr=...)com queryset já filtrado por ORCID.
).prefetch_related(
"researcheraka_set__researcher_identifier",
)
for old_researcher in old_researchers:
orcid = (
old_researcher.researcheraka_set.filter(
researcher_identifier__source_name__iexact="ORCID"
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| obj.save_file( | ||
| f"{pid_provider_xml.v3}.xml", xml_with_pre.tostring(pretty_print=True) | ||
| ) | ||
| # Único save final após salvar o arquivo | ||
| obj.save() |
tracker/tasks.py
Outdated
| @@ -12,16 +12,6 @@ | |||
| User = get_user_model() | |||
| @@ -26,21 +27,14 @@ | |||
| User = get_user_model() | |||
| DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=0) or env.int("DJANGO_CONN_MAX_AGE", default=60) # noqa F405 | ||
| # Reutilizar conexões por 60s por padrão para reduzir overhead de reconexão. | ||
| # Em produção com gunicorn+gevent ou Celery, isto evita abrir/fechar conexão a cada request. | ||
| DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 |
| # Hard time limit: o worker é terminado (SIGKILL) após este tempo. | ||
| # Deve ser MAIOR que o soft time limit. | ||
| CELERY_TASK_TIME_LIMIT = env.int('CELERY_TASK_TIME_LIMIT', default=36000) | ||
| # http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-soft-time-limit | ||
| # TODO: set to whatever value is adequate in your circumstances | ||
| CELERY_TASK_SOFT_TIME_LIMIT = 36000 | ||
| # Soft time limit: levanta SoftTimeLimitExceeded, permitindo cleanup. | ||
| # Deve ser MENOR que o hard time limit. | ||
| CELERY_TASK_SOFT_TIME_LIMIT = env.int('CELERY_TASK_SOFT_TIME_LIMIT', default=3600) |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
O PR aplica um conjunto amplo de otimizações para reduzir consultas ao banco (evitando N+1), eliminar save()/UPDATEs desnecessários e ajustar configurações para reduzir pressão de conexões PostgreSQL em produção.
Changes:
- Otimizações de querysets (principalmente
select_related/prefetch_related) em admin Wagtail, tasks e fluxos de exportação/importação. - Refactors para reduzir gravações redundantes (consolidação de
save()e flags de “changed”) em vários models. - Ajustes operacionais em settings (persistent connections, sessions no Redis, tuning do Celery) e consolidação do helper
_get_user.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tracker/tasks.py | Remove helper _get_user local; ajustes correlatos na task. |
| thematic_areas/wagtail_hooks.py | Adiciona get_queryset() com select_related("creator") para reduzir N+1 no admin. |
| researcher/tasks.py | Adiciona select_related/prefetch_related para reduzir queries na migração de researchers. |
| researcher/models.py | Troca loop por values_list(...).first() nas properties orcid/lattes. |
| pid_provider/tasks.py | Consolida import de _get_user (mas introduz duplicação crítica de task). |
| pid_provider/models.py | Ajusta save()/select_related e consolida persistência em fluxos de versão/other pid. |
| organization/tasks.py | Amplia select_related em task de migração para evitar N+1. |
| organization/models.py | Refatora updates (logo/url/instituições) para evitar save() desnecessário. |
| location/wagtail_hooks.py | Adiciona select_related no queryset do admin de Location. |
| location/scripts/bulk_cities.py | Move busca do usuário para fora do loop para evitar N queries. |
| location/models.py | Introduz flag changed e otimiza get_country() com .first() + select_related. |
| journal/models.py | Remove save() redundante em M2M, otimiza lookups e usa update_or_create. |
| issue/wagtail_hooks.py | Adiciona select_related("creator","updated_by") para reduzir N+1. |
| institution/models.py | Introduz flag changed para evitar UPDATEs quando não há alteração real. |
| editorialboard/views.py | Reusa request.user dentro do loop para evitar acessos repetidos. |
| core/wagtail_hooks.py | Otimiza queryset do admin de License com select_related("creator"). |
| core/utils/utils.py | Consolida _get_user priorizando request.user autenticado. |
| core/middleware.py | Reusa queryset de coleções do usuário para evitar queries duplicadas. |
| config/settings/production.py | Ajusta conexões persistentes e migra sessions para cache (Redis). |
| config/settings/base.py | Ajusta time limits e parâmetros do Celery; evita backend django-db para resultados. |
| collection/tasks.py | Corrige lógica de seleção do usuário (if/elif/else) e validação explícita. |
| bigbang/tasks.py | Passa a usar _get_user centralizado. |
| article/controller.py | Adiciona select_related no iterator do bulk export para reduzir N+1. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| obj.save_file( | ||
| f"{pid_provider_xml.v3}.xml", xml_with_pre.tostring(pretty_print=True) | ||
| ) | ||
| # Único save final após salvar o arquivo | ||
| obj.save() |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
1 similar comment
|
@copilot open a new pull request to apply changes based on the comments in this thread |
| ): | ||
| try: | ||
| user = _get_user(user_id, username) | ||
| user = _get_user(request=None, user_id=user_id, username=username) |
There was a problem hiding this comment.
@copilot trocar request=None por request=self.request
| def task_create_tasks(self, user_id=None, username=None, tasks_data=None): | ||
| if not tasks_data: | ||
| user = _get_user(user_id, username) | ||
| user = _get_user(request=None, user_id=user_id, username=username) |
There was a problem hiding this comment.
@copilot trocar request=None por request=self.request
| elif username: | ||
| user = User.objects.get(username=username) | ||
| else: | ||
| raise ValueError("user_id or username is required") |
There was a problem hiding this comment.
@copilot obtenha o usuário conforme foi feito em outras tarefas com from core.utils.utils import _get_user
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Conjunto de otimizações para reduzir o volume de queries e writes no PostgreSQL (N+1 em admin/tasks/iteradores, eliminação de saves redundantes) e diminuir pressão de conexões em produção (reuso de conexão, sessão em Redis, ajustes de Celery), além de consolidar _get_user em um ponto único.
Changes:
- Otimiza querysets (principalmente com
select_related/prefetch_related) em Wagtail admin, tasks e rotinas de exportação/migração. - Reduz writes desnecessários ao consolidar
save()no chamador e evitar updates quando não há mudança efetiva. - Ajusta configurações (produção/base) para reduzir pressão no PostgreSQL (CONN_MAX_AGE, sessions em cache/Redis, settings de Celery) e remove
_get_userduplicado.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tracker/tasks.py | Remove _get_user duplicado e simplifica assinatura da task de limpeza. |
| thematic_areas/wagtail_hooks.py | Adiciona select_related("creator") para evitar N+1 nas listagens do admin. |
| researcher/tasks.py | Adiciona select_related/prefetch_related para migração de researchers. |
| researcher/models.py | Otimiza properties orcid/lattes com values_list(...).first() para reduzir carga e colunas lidas. |
| pid_provider/tasks.py | Passa a importar _get_user de core.utils.utils (remoção de duplicação). |
| pid_provider/models.py | Otimiza consultas (ex.: select_related("current_version")) e consolida saves no fluxo de registro/versões. |
| organization/tasks.py | Adiciona select_related adicional para reduzir queries durante migração. |
| organization/models.py | Refatora updates de logo/url e consolida save() no chamador; update_institutions retorna bool. |
| location/wagtail_hooks.py | Adiciona select_related no queryset do admin para evitar N+1 (country/state/city/creator). |
| location/scripts/bulk_cities.py | Evita User.objects.get() dentro do loop (remove N queries). |
| location/models.py | Evita save() quando não houve mudança e otimiza busca de país por nome. |
| journal/models.py | Remove loops desnecessários, reduz saves, e evita N+1 ao acessar coleções/legacy keys. |
| issue/wagtail_hooks.py | Adiciona select_related para creator/updated_by no queryset do admin. |
| institution/models.py | Evita save() quando não houve mudança em create_or_update. |
| editorialboard/views.py | Reusa request.user fora do loop para evitar acessos repetidos. |
| core/wagtail_hooks.py | Adiciona select_related("creator") no queryset do admin de License. |
| core/utils/utils.py | Consolida/ajusta _get_user para priorizar request.user autenticado antes de queries. |
| core/middleware.py | Reusa o mesmo QuerySet de collections para evitar duplicação e potencial requery. |
| config/settings/production.py | Ajusta conexões do DB (CONN_MAX_AGE/health checks) e move sessões para cache (Redis). |
| config/settings/base.py | Ajusta time limits e reciclagem/concurrency de workers Celery; remove backend “django-db” comentando. |
| collection/tasks.py | Corrige fluxo de seleção de usuário (if/elif/else) e adiciona erro explícito quando ausente. |
| bigbang/tasks.py | Passa a usar _get_user centralizado (remove função local). |
| article/controller.py | Otimiza iteração do bulk export com select_related(...) para reduzir queries. |
Comments suppressed due to low confidence (1)
researcher/tasks.py:37
- O
prefetch_related("researcheraka_set__researcher_identifier")não é aproveitado porque no loop você usaold_researcher.researcheraka_set.filter(...).first(), o que normalmente dispara uma query por pesquisador. Para realmente eliminar o N+1, prefiraPrefetchcom queryset já filtrado (ex.: apenas ORCID) usandoto_attr, ou então leia o ORCID a partir da lista prefetched (old_researcher.researcheraka_set.all()) sem.filter().
old_researchers = Researcher.objects.filter(
researcheraka__researcher_identifier__source_name="ORCID",
researcheraka__researcher_identifier__identifier__isnull=False,
).select_related(
"person_name",
"affiliation__institution__institution_identification",
"affiliation__institution__location",
).prefetch_related(
"researcheraka_set__researcher_identifier",
)
for old_researcher in old_researchers:
orcid = (
old_researcher.researcheraka_set.filter(
researcher_identifier__source_name__iexact="ORCID"
)
.first()
.researcher_identifier.identifier
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Salvar primeiro sem arquivo para obter o PK | ||
| obj.save() | ||
| # save_file já faz self.file.save() que persiste o campo file, | ||
| # mas precisamos persistir o registro completo com o path do arquivo | ||
| obj.save_file( | ||
| f"{pid_provider_xml.v3}.xml", xml_with_pre.tostring(pretty_print=True) | ||
| ) | ||
| # Único save final após salvar o arquivo | ||
| obj.save() |
| @@ -26,21 +27,14 @@ | |||
| User = get_user_model() | |||
| except Exception as e: | ||
| return None |
| except Exception as e: | ||
| return None |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
O que esse PR faz?
Aplica um conjunto de otimizações para reduzir o número de queries ao banco de dados, eliminar saves desnecessários e diminuir a pressão sobre conexões PostgreSQL em produção.
As mudanças se organizam em cinco frentes:
1. Eliminação de N+1 queries no admin Wagtail
Adiciona
select_relatednos métodosget_querysetdosSnippetViewSetdeLocation,Issue,License,GenericThematicArea,ThematicAreae seus arquivos associados. Sem isso, listar N registros no admin disparava uma query extra por linha para resolver FKs comocreator,updated_by,journalecountry.2. Eliminação de N+1 queries em models e tasks
Adiciona
select_relatedem métodos que iteravam querysets sem JOIN:Journal.collection_acrons,Journal.get_ids,Journal.get_legacy_keys,PidProviderXML.public_items,PidProviderXML.best_matchese na task de migração deorganization. Adicionaprefetch_related('researcheraka_set__researcher_identifier')na task de migração de researchers.3. Redução de queries pontuais
breakpor.filter().first()emOfficialJournal.add_old_title/add_new_titleeCountryName.get_countryvalues_list(..., flat=True).first()nas propertiesorcidelattesdeResearcher, projetando apenas a coluna necessária comLIMIT 1get/except + saveporupdate_or_createemJournalHistory.loadUser.objects.get()para fora do loop embulk_cities.py, eliminando N queries durante importação CSVselect_related('journal', 'journal__official', 'pp_xml')no iterator debulk_export_articles_to_articlemeta4. Eliminação de saves desnecessários
Introduz flag
changedantes de chamarsave()nos métodoscreate_or_updatedeInstitution,InstitutionIdentification,State,CountryNameeCountry: oUPDATEsó é emitido quando há mudança efetiva de valor. RefatoraOrganization.update_logo/update_urlpara retornarboole consolidar osave()no chamador. Consolida saves internos emPidProviderXMLeXMLVersion, delegando o save final ao chamador.5. Redução de pressão sobre conexões PostgreSQL
CONN_MAX_AGE=60: reutiliza conexões abertas pelo worker por até 60 segundos, evitando abrir/fechar conexão a cada requestCONN_HEALTH_CHECKS=True: valida a conexão reutilizada antes de usá-laPOOL_OPTIONS: incompatível comdjango-prometheuse estava sendo ignoradoSESSION_ENGINE=cache+SESSION_CACHE_ALIAS=default: migra sessões do PostgreSQL para o Redis, reduzindo writes no banco comSESSION_SAVE_EVERY_REQUEST=TrueCELERY_RESULT_BACKEND='django-db': evita writes de resultado de task no PostgreSQL; Redis já é o backend configuradoCELERY_WORKER_MAX_TASKS_PER_CHILD=100: recicla workers após 100 tarefas, liberando conexões acumuladas6. Consolidação de
_get_userRemove definições locais de
_get_userduplicadas embigbang/tasks.py,pid_provider/tasks.pyetracker/tasks.py. Todas passam a importar decore.utils.utils, onde a função foi corrigida para priorizarrequest.userautenticado antes de consultar o banco poruser_idouusername.7. Correção de bug em
collection/tasks.pySubstitui
if/ifporif/elif/elseemtask_load_collections, evitando reatribuição silenciosa deuserquando ambosuser_ideusernamesão fornecidos. AdicionaValueErrorexplícito quando nenhum dos dois é passado.Onde a revisão poderia começar?
core/utils/utils.py— nova assinatura de_get_usere lógica de prioridade de autenticaçãojournal/models.py—add_new_titleremove oself.save()interno; verificar se todos os chamadores existentes salvam o objeto após chamar o métodoorganization/models.py—update_institutionspassa a retornarbool; verificar chamadores externos ao módulopid_provider/models.py— consolidação de saves em_add_current_versione_add_other_pid; o save final está em_save()do objeto paiconfig/settings/production.py— mudanças deSESSION_ENGINEe remoção dePOOL_OPTIONSrequerem atenção em deployComo este poderia ser testado manualmente?
django-silk) e navegar pelas listagens do admin Wagtail paraLocation,Issue,LicenseeThematicArea— o número de queries por página deve cair visivelmentebulk_export_articles_to_articlemetacom um queryset de ~500 artigos e comparar o tempo de execução e número de queries antes/depoismigrate_old_researcher_to_new_researchere verificar via logs que não há queries repetidas por researchertask_load_collectionssemuser_ide semusernamee confirmar queValueErroré levantadopg_stat_activityantes e depois do deploy — espera-se redução comCONN_MAX_AGE=60e sessões no Redisdjango.contrib.sessions) estão sendo criadas após o deployAlgum cenário de contexto que queira dar?
O conjunto de mudanças foi motivado por pressão crescente de conexões no PostgreSQL em produção, especialmente durante execuções concorrentes de tasks Celery que iteravam querysets grandes sem
select_related. O admin Wagtail com listagens de centenas de registros também gerava picos de queries observados via monitoramento.A remoção de
POOL_OPTIONSé necessária porque o backenddjango-prometheusnão é compatível com o pooling nativo do Django, fazendo as opções serem silenciosamente ignoradas. A estratégia adotada éCONN_MAX_AGEpor worker, que é compatível e suficiente para o perfil de carga atual.Screenshots
N/A — mudanças de backend sem alteração de interface
Quais são tickets relevantes?
Adicionar referências aos tickets correspondentes
Referências
select_relatedCONN_MAX_AGEworker_max_tasks_per_child