suggest-indexes proposes composite indexes that include the primary key or a unique field
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 82/100
調査の方向性
cli/orm_lens/query_analyzer.py の suggest_indexes() から始めてください。ここでは pk_name と target_model が利用できます。その後、_propose_indexes() の先頭にある複合インデックスのループを読んでください。単一列のユニークな集合(PK、pk、primary_key=True または unique=True のフィールド、OneToOneFields)を作り、そのいずれかを含む複合インデックスはスキップしてください。単一フィールドのロジックには手を加えないでください。Story の再現で ['status'] と ['title'] のみが得られ、pk= が id= と同様に動作し、cli/tests/test_query_analyzer.py と pytest、ruff、mypy がすべて通れば完了です。
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- Python
- スター
- 84
- フォーク
- 13
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
FROWNINGdev/django-orm-lens のほかの issue
-
`migration-risk` text output prints `app.None` for graph-level findings対応中かも @phoenixbycaselka が今日担当しました。 オープンbug good first issue python
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
FROWNINGdev/django-orm-lens#268 ·
-
Finish the Chinese rule reference — DOL001–DOL007再び着手できるかも @harbinresearcher が 64 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンdocumentation good first issue help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
FROWNINGdev/django-orm-lens#81 · コメント 2 件 ·
-
Fields inherited from Django's `AbstractBaseUser` / `PermissionsMixin` / `AbstractUser` are missingオープンbug good first issue python
難易度 3/5 1〜2日 初心者へのやさしさ 62/100
FROWNINGdev/django-orm-lens#267 ·
-
bug good first issue python
難易度 3/5 半日 初心者へのやさしさ 78/100
FROWNINGdev/django-orm-lens#266 ·
-
enhancement help wanted python
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
FROWNINGdev/django-orm-lens#254 ·
FROWNINGdev/django-orm-lens の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
roman-corgi/corgisim#327 ·
メンテナーはふだん 2 日以内に返信
-
[Bug]: opencode_go chat route drops reasoning_effort (even 'none'), while the same endpoint honors it via custom_llm_provider=openai対応中かも @arvindkumar-ship-it が今日担当しました。 オープンllm translation
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
BerriAI/litellm#51871 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
PolicyEngine backdates South Carolina’s EITC into 2015–2017対応中かも @MaxGhenis が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
PolicyEngine/policyengine-us#10944 ·
メンテナーはふだん 2 日以内に返信
-
fix(frontend): resolve SSE parser crash on unhandled Ref methods and undefined actions identifierオープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
kodokbakar/MiroFish-Local#94 ·
メンテナーはふだん 1 日以内に返信