BLOGサブスレッドの日常
2018.06.04
Django の makemigrations で作成したファイルを微調整する
torikai
月曜日担当の鳥飼です。
お久しぶりです。よろしくお願いします。
Django
使っていますか? 私はまだまだお世話になっています。Django
便利。
Django
の便利な機能として、モデルに変更があればマイグレーションの形で保存し、DBに変更を反映できる便利な機能があります。
基本的には、この生成されたマイグレーションファイルをそのまま使うのですが、+αの対応を入れたい場合があります。
そんな時はマイグレーションファイルをちょっと調整するだけで解決できるかもしれませんよ(・ω・)ノ
今回は、その調整例をご紹介。
追加した列に対して、既存のデータに合わせて初期値を設定したい
こんなマイグレーションファイルが生成されたとしまして…
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2018-06-04 09:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='Hoge',
name='code',
field=models.CharField(default=None, max_length=20, null=True, verbose_name='hoge識別コード'),
),
]
例えば、既存データに対して、
id
< 100 の場合の初期値はhoge
- 100 <=
id
< 200 の場合の初期値はhige
- それ以外は
hage
…としたいな、という場合。
SQLやコマンドを別途用意するのも良いのですが、マイグレーションファイルを以下のように調整しても良いんです。
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2018-06-04 09:47
from __future__ import unicode_literals
from django.db import migrations, models
# 追加
def initialize(apps, schema_editor):
# 第一引数はアプリ名、第二引数はモデル名を指定
Hoge = apps.get_model('app', 'Hoge')
# migrate 時に実行したい処理を記述
for hoge in Hoge.objects.all():
hoge.code = 'hage'
if hoge.id < 100:
hoge.code = 'hoge'
if 100 <= hoge.id < 200:
hoge.code = 'hige'
hoge.save()
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='Hoge',
name='code',
field=models.CharField(default=None, max_length=20, null=True, verbose_name='hoge識別コード'),
),
migrations.RunPython(initialize) # 追加
]
このマイグレーションファイルをmigrate
すると、initialize()
の処理が実行され、code
に値がセットされます。
上記のコードの場合だと、code
列を追加した後に初期値を更新する処理が実行されます。
もちろん、migrations.AddField
より前にmigrations.RunPython()
を指定することもできます(・ω・)ノ
これで何が嬉しいか
「このマイグレーションを実行した後は、コレコレこういうSQLを実行してください」とか
「このショットのコマンドを実行してください」とか
「リリース作業時にはmigrate
とは別に別途このような作業が必要」とか
そういう 「後々コケるので、やる必要がある作業」 が不要になるということです。ブラボー。
migrate
すればよろしくやってくれるという訳なので、意識しなければならないことが減って気持ち的にもヘルシーですね。
今日のひとネタでした(・ω・)ノ
この記事を書いた人
torikai