Models in a sub-package of an app get the sub-package's label (`io_storages/s3/models.py` → app `s3`)

オープン
#266 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
半日
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
django, python
領域
tooling

調査の方向性

The app label is set inline in parse_models_file() in cli/orm_lens/parser.py (around lines 610-614), and the same rule lives in _app_dir_for() in cli/orm_lens/_paths.py. Start by reproducing the io_storages/s3/models.py layout and running orm-lens list and drift, then look at how both call sites derive the app. Done means list shows io_storages.S3ImportStorage, drift reports nothing, the existing shop/ cases keep their labels, and cd cli && python -m pytest -q passes.

索引モデルが issue の本文から書いたものです。

説明

bug good first issue python

Source: label-studio — label_studio/io_storages/{s3,gcs,azure_blob,redis,localfiles}/models.py

What happens

The app label comes from the directory that holds models.py (or from the parent of a models/ package). That breaks for apps that split models into sub-packages:

io_storages/
    apps.py
    migrations/
    models.py          # from .s3.models import S3ImportStorage
    s3/models.py       # class S3ImportStorage(models.Model)

Django puts S3ImportStorage in io_storages: the label comes from the app config whose package contains the module, not from the file's own directory. orm-lens calls the app s3.

On label-studio list shows s3.S3ImportStorage, gcs.GCSImportStorage and so on, describe io_storages.S3ImportStorage fails, and drift prints 25 "migrated, but models.py does not declare it" lines for io_storages.*.

Repro

io_storages/__init__.py, io_storages/migrations/__init__.py, io_storages/s3/__init__.py: empty.

io_storages/models.py

from .s3.models import S3ImportStorage  # noqa: F401

io_storages/s3/models.py

from django.db import models


class S3ImportStorage(models.Model):
    bucket = models.TextField(null=True, blank=True)
    prefix = models.TextField(null=True, blank=True)

io_storages/migrations/0001_initial.py

from django.db import migrations, models


class Migration(migrations.Migration):
    initial = True
    dependencies = []
    operations = [
        migrations.CreateModel(
            name="S3ImportStorage",
            fields=[
                ("id", models.AutoField(primary_key=True, serialize=False)),
                ("bucket", models.TextField(null=True, blank=True)),
                ("prefix", models.TextField(null=True, blank=True)),
            ],
        ),
    ]
$ orm-lens list
s3.S3ImportStorage

$ orm-lens describe io_storages.S3ImportStorage
error: model 'io_storages.S3ImportStorage' not found

$ orm-lens drift
 ~ io_storages.s3importstorage: migrated, but models.py does not declare it
     stale table, or the model lives outside the parsed tree

summary: 1 model(s) drifted, 0 blocking, 1 migration(s) replayed

Expected: io_storages.S3ImportStorage, no drift.

Where
  • cli/orm_lens/parser.py, lines 610–614 in parse_models_file() (line 498): sets app_name from the parent directory, or the grandparent for models/.
  • cli/orm_lens/_paths.py, line 21, _app_dir_for(): the same rule, used to group models into apps (parser.py:1191) and to pick a base class in the same app (parser.py:826). Both have to agree.
Suggested fix

Put the lookup in _app_dir_for() and use it from parse_models_file() too, instead of the inline copy:

  1. Start at the directory of the file (or the parent of a models/ package, as now).
  2. If that directory has migrations/ or apps.py, it's the app.
  3. Otherwise go up while the parent is still a package (has __init__.py) and stop at the first directory that has migrations/ or apps.py.
  4. Nothing found: today's rule.

The __init__.py check keeps the walk inside the project. Meta.app_label is a separate case, leave it out.

src/parser.ts has the same rule (around lines 380 and 632). A Python-only fix is fine, leave a note in the PR for the TS side.

How to test
  • A new test with the repro: list gives io_storages.S3ImportStorage, drift reports nothing.
  • A plain app (shop/models.py) and a models/ package (shop/models/order.py) keep their labels.
  • A models.py in a folder with no migrations/ or apps.py above it keeps today's label.
  • Run the golden snapshots. If a project changes, update it and list the changes in the PR.
  • cd cli && python -m pytest -q, ruff and mypy pass.

Difficulty: good first issue, one helper and a few tests.

主要言語
Python
スター
84
フォーク
13
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

FROWNINGdev/django-orm-lens のほかの issue

FROWNINGdev/django-orm-lens の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。