🎩

Djangoで全テーブルのIDの採番状況をチェックする

2023/05/02に公開

小ネタです🍣

DjangoのModelにデフォルトで存在するidフィールドについて、idをどの程度採番しているか簡単にチェックするためのスクリプトです
全モデルの全フィールドを走査し、AutoFieldがあったら Model.objects.latest(*fields) を出力します

https://docs.djangoproject.com/en/4.2/ref/models/querysets/#latest

本スクリプトはSQLを扱わないため、MySQLでもPostgreSQLでも同様の結果を得ることができるものと思います
しかしながら、この実装だと最新のidが削除済みの場合に実際より採番位置が少なく見えてしまうため、正確な空き状況を調べたい場合は SHOW TABLE STATUS 等の利用を検討した方がいいかもしれません

https://dev.mysql.com/doc/refman/8.0/ja/show-table-status.html

python manage.py shell などでREPLを起動し、以下のスクリプトを実行してください
本番環境での実行は自己責任にてお願いします🐘

def describe_remaining_id_length():
    import django.apps
    from django.db.models import AutoField, BigAutoField, SmallAutoField
    results = []
    print('Iterate all Models', end="")
    for model in django.apps.apps.get_models():
        model_name = model.__name__
        for field in model._meta.get_fields():
            if isinstance(field, AutoField):
                field_name = field.name
                try:
                    latest_model = model.objects.latest(field_name)
                    latest_id = getattr(latest_model, field_name)
                except model.DoesNotExist:
                    latest_id = 0

                if isinstance(field, BigAutoField):
                    int_max = 9_223_372_036_854_775_807
                elif isinstance(field, SmallAutoField):
                    int_max = 32_767
                else:
                    int_max = 2_147_483_647

                field_type_name = type(field).__name__
                remaining = int_max - latest_id

                results.append({
                    'model_name': model_name,
                    'field_name': field_name,
                    'field_name_type': field_type_name,
                    'latest_id': latest_id,
                    'remaining': remaining,
                })
                print(".", end="")
    print('')
    print('')
    results = sorted(results, key=lambda x: x['remaining'])

    print('model_name,field_name,field_name_type,latest_id,remaining')
    for result in results:
        print(f"{result['model_name']},{result['field_name']},{result['field_name_type']},{result['latest_id']},{result['remaining']}")


describe_remaining_id_length()

結果のイメージは以下です
表は remaining カラム(空きID)の昇順で出力されます

Iterate all Models.......................

model_name,field_name,field_name_type,latest_id,remaining
HogeModel,id,AutoField,474505342,1672978305
FugaModel,id,AutoField,390425574,1757058073
略
PiyoModel,id,BigAutoField,72555344,9223372036782220463

そんだけ😌

Discussion