Django のマイグレーション (2023年5月28日ゼミ)

昨日のPythonウェブプログラミングゼミで、ライブ収録総計時間が50時間を超えたよう。

Pythonウェブプログラミングゼミライブ収録

ずいぶん行ったなぁと思う。
月2回、なんだかんだと、毎回3時間近くやっている。

今回扱ったテーマは、Django のマイグレーション。

まず、マイグレーションの基本の流れ。

そして、関連の manage.py コマンドを紹介。

コマンド 説明
makemigrations マイグレーションファイルを生成する。
モデルの変更を検出してマイグレーションファイルを生成できるほか、 --empty オプションで空のマイグレーションを作ることもできる。
migrate 生成されたマイグレーションファイルの内容をデータベースに適用する。
適用履歴は django_migrations テーブルに保存される。
sqlmigrate マイグレーションファイルが生成するSQL文を表示する。
デバッグに使える。
showmigrations プロジェクト内のマイグレーションの一覧を表示する。
適用済みと未適用のマイグレーションを確認できる。
squashmigrations 複数のマイグレーションファイルをひとつにまとめる。
(今日紹介した中ではプライオリティは低い)
dbshell データベースにログインし、直接SQLを発行できる状態にする。
(今日紹介した中ではプライオリティは低い)

ref: 公式ドキュメント django-admin と manage.py

これらについてオプションを示しつつサンプルコードを動かしつつ解説。

後半は、データマイグレーションのやり方について。
python manage.py makemigrations app_name --empty で空のマイグレーションファイル作成。
そして、以下の類のコードを書く。

from django.db import migrations

def set_comment_is_public(apps, schema_editor):
    Comment = apps.get_model('log', 'Comment')
    comments = []
    for comment in Comment.objects.all().select_related('user', 'article__user'):
        if comment.user == comment.article.user:
            comment.is_public = True
            comments.append(comment)
    Comment.objects.bulk_update(comments, ['is_public'])


class Migration(migrations.Migration):
    dependencies = [
        ('log', '0006_comment_is_public'),
    ]

    operations = [
        migrations.RunPython(set_comment_is_public),
    ]

RunPython の引数は、2つの引数 apps, schema_editor を受け取る callable。

巻き戻しできるようにするには、 reverse_code も記述する。
(巻き戻し時にやるべき処理が特に無い場合は、 migrations.RunPython.noop で OK)

class Migration(migrations.Migration):
    dependencies = [
        ('log', '0006_comment_is_public'),
    ]

    operations = [
        migrations.RunPython(set_comment_is_public, reverse_code=reverse_set_comment_is_public),

        # もっとも、何もする必要がない場合は、以下のように記述することもある
        # migrations.RunPython(set_comment_is_public, reverse_code=migrations.RunPython.noop),),
    ]
公開日時: 2023/05/29 06:30