suggest-indexes proposes composite indexes that include the primary key or a unique field
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 82/100
Direzione di ricerca
Inizia da cli/orm_lens/query_analyzer.py in suggest_indexes(), dove sono disponibili pk_name e target_model, poi leggi il ciclo sui composti in cima a _propose_indexes(). Costruisci un insieme di colonne singole uniche (la PK, pk, i campi con primary_key=True o unique=True, e gli OneToOneFields) e salta ogni composto che ne contiene una, lasciando invariata la logica dei campi singoli. È fatto quando il repro di Story produce solo ['status'] e ['title'], pk= si comporta come id=, e cli/tests/test_query_analyzer.py insieme a pytest, ruff e mypy passano.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Source: weblate — trans.Unit: models.Index(fields=['id', 'translation'])
What happens
filter(id=pk, title=title) seen twice gives models.Index(fields=['id', 'title']). The primary key is unique: an equality lookup on it returns at most one row, so the PK index already answers the query and a composite led by id only costs writes and disk. The same is true for any unique=True field.
_propose_indexes() uses already_indexed for single-field proposals only. The composite loop checks the M2M/reverse filter from #252/#263 and existing Meta groups, nothing else. pk= is folded into id before that, so both spellings hit it.
On weblate trans.Unit gets models.Index(fields=['id', 'translation']).
Repro
board/models.py
from django.db import models
class Story(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
status = models.CharField(max_length=20)
board/stats.py
from .models import Story
def by_id_and_title(pk, title):
return Story.objects.filter(id=pk, title=title).first()
def by_id_and_title_again(pk, title):
return Story.objects.get(id=pk, title=title)
def by_pk_and_status(pk, status):
return Story.objects.filter(pk=pk, status=status).exists()
def by_pk_and_status_again(pk, status):
return Story.objects.filter(pk=pk, status=status).first()
def by_slug_and_status(slug, status):
return Story.objects.filter(slug=slug, status=status).first()
def by_slug_and_status_again(slug, status):
return Story.objects.filter(slug=slug, status=status).exists()
$ orm-lens suggest-indexes board.Story
target: board.Story
proposed Meta.indexes (5):
models.Index(fields=['id', 'status']), # 2 composite filter sites
models.Index(fields=['id', 'title']), # 2 composite filter sites
models.Index(fields=['slug', 'status']), # 2 composite filter sites
models.Index(fields=['status']), # 4 filter sites
models.Index(fields=['title']), # 2 filter sites
Expected: only ['status'] and ['title']. The usage table can keep listing id + title etc.
Where
cli/orm_lens/query_analyzer.py
- line 497,
_propose_indexes(); the composite loop is right at the top of the function body; - line 309,
_indexed_single_fields(): buildsalready_indexed, but it also containsdb_index=Truefields and FKs, which are not unique, so it can't be reused as is; - line 598,
suggest_indexes():pk_name(line 675) andtarget_modelare both there.
Suggested fix
In suggest_indexes(), build the set of unique single columns: pk_name, "pk", every field with primary_key=True or unique=True (the _PK_TRUE_RE / _UNIQUE_TRUE_RE regexes are already in the module), and OneToOneFields (unique by definition). Pass it to _propose_indexes() as a new keyword argument and skip a composite combo that contains any of these names.
Don't touch the single-field and order_by logic.
How to test
cli/tests/test_query_analyzer.py: the repro gives exactly['status']and['title'].filter(pk=..., ...)is dropped the same asfilter(id=..., ...).- A model with
code = models.CharField(primary_key=True)drops a['code', 'title']composite. - A composite of two non-unique fields (
filter(title=..., status=...)) is still proposed. cd cli && python -m pytest -q,ruffandmypypass.
Difficulty: good first issue, one set and one if.
- Lingua principale
- Python
- Stelle
- 84
- Fork
- 13
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di FROWNINGdev/django-orm-lens
-
`migration-risk` text output prints `app.None` for graph-level findingsForse già presa @phoenixbycaselka l’ha presa oggi. Apertabug good first issue python
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
FROWNINGdev/django-orm-lens#268 ·
-
Finish the Chinese rule reference — DOL001–DOL007Forse di nuovo libera @harbinresearcher l’ha presa 64 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation good first issue help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
FROWNINGdev/django-orm-lens#81 · 2 commenti ·
-
Fields inherited from Django's `AbstractBaseUser` / `PermissionsMixin` / `AbstractUser` are missingApertabug good first issue python
Difficoltà 3/5 1-2 giorni Idoneità per principianti 62/100
FROWNINGdev/django-orm-lens#267 ·
-
bug good first issue python
Difficoltà 3/5 Mezza giornata Idoneità per principianti 78/100
FROWNINGdev/django-orm-lens#266 ·
-
enhancement help wanted python
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
FROWNINGdev/django-orm-lens#254 ·
Tutte le issue di FROWNINGdev/django-orm-lens
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
roman-corgi/corgisim#327 ·
I maintainer di solito rispondono entro 2 giorni
-
[Bug]: opencode_go chat route drops reasoning_effort (even 'none'), while the same endpoint honors it via custom_llm_provider=openaiForse già presa @arvindkumar-ship-it l’ha presa oggi. Apertallm translation
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
BerriAI/litellm#51871 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
PolicyEngine backdates South Carolina’s EITC into 2015–2017Forse già presa @MaxGhenis l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
PolicyEngine/policyengine-us#10944 ·
I maintainer di solito rispondono entro 2 giorni
-
fix(frontend): resolve SSE parser crash on unhandled Ref methods and undefined actions identifierApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
kodokbakar/MiroFish-Local#94 ·
I maintainer di solito rispondono entro 1 giorno