
今回とりあえず触ったのはこちらの手順。ありがとうございます。
データベースのマイグレーション
コードのModelの情報に従ってデータベースのマイグレーションをしてくれるコードですね。
python3 manage.py migration
これに合わせてテーブルが作成されたり、消されたり、カラム操作が行われます。そう考えるとひじょーーーに怖いです。本番環境でデータベースをよしなに操作してくれるって怖さしかないです。
というかそもそもデータベースのマイグレーションって一般的なの?っていうところから調べるました。するとこの記事がヒット。
いろんな理由がありますがマイグレは一般的なこと。ただし実施する際に様々な観点を考慮する必要があるとのこと。(そりゃそうだ)
実際にカラムを消すようにmodelを修正してmakemigraionsを実行する。
% python3 manage.py makemigrations
Migrations for 'app':
app/migrations/0002_auto_20210418_2249.py
- Remove field sample_1 from item
- Alter field sample_9 on item
すると以下のようなpythonファイルが生成されていた。中身を見るとカラムを1つ削除する内容が書かれていた。(ちなみにこのファイルを削除してもmakemigraionsは復活する)
# Generated by Django 2.1.2 on 2021-04-18 13:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='item',
name='sample_1',
),
]
これ消して戻してってやったらひたすら000X_auto_yyyymmdd_hhmm.pyファイルが生成される…。Ansibleみたいだな…。これは世の中の人めんどくさーって思っていそう。
現場の方はどうされているのかを質問してみています。
Python - Djangoにおけるmake migrationsはどのタイミングで実施しどう管理すべきですか?|teratail
ちなみにmigrateにて実行されるSQLの中をチェックする場合は以下のコマンドを実行しましょう。
% python3 manage.py sqlmigrate app 0005_auto_20210418_2332
BEGIN;
--
-- Add field sample_1 to item
--
ALTER TABLE "app_item" RENAME TO "app_item__old";
CREATE TABLE "app_item" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "sample_1" varchar(21) NULL, "sample_2" text NULL, "sample_3" integer NULL, "sample_4" real NULL, "sample_5" decimal NULL, "sample_6" bool NOT NULL, "sample_7" date NULL, "sample_8" datetime NULL, "sample_9" integer NULL, "created_at" datetime NULL, "updated_at" datetime NULL, "created_by_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED, "sample_10_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED, "updated_by_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED);
INSERT INTO "app_item" ("id", "sample_2", "sample_3", "sample_4", "sample_5", "sample_6", "sample_7", "sample_8", "sample_9", "created_at", "updated_at", "created_by_id", "sample_10_id", "updated_by_id", "sample_1") SELECT "id", "sample_2", "sample_3", "sample_4", "sample_5", "sample_6", "sample_7", "sample_8", "sample_9", "created_at", "updated_at", "created_by_id", "sample_10_id", "updated_by_id", NULL FROM "app_item__old";
DROP TABLE "app_item__old";
CREATE INDEX "app_item_created_by_id_a8ffed89" ON "app_item" ("created_by_id");
CREATE INDEX "app_item_sample_10_id_c24ee555" ON "app_item" ("sample_10_id");
CREATE INDEX "app_item_updated_by_id_580f5996" ON "app_item" ("updated_by_id");
--
-- Alter field sample_9 on item
--
ALTER TABLE "app_item" RENAME TO "app_item__old";
CREATE TABLE "app_item" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "sample_2" text NULL, "sample_3" integer NULL, "sample_4" real NULL, "sample_5" decimal NULL, "sample_6" bool NOT NULL, "sample_7" date NULL, "sample_8" datetime NULL, "created_at" datetime NULL, "updated_at" datetime NULL, "created_by_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED, "sample_10_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED, "updated_by_id" integer NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED, "sample_1" varchar(21) NULL, "sample_9" integer NULL);
INSERT INTO "app_item" ("id", "sample_2", "sample_3", "sample_4", "sample_5", "sample_6", "sample_7", "sample_8", "created_at", "updated_at", "created_by_id", "sample_10_id", "updated_by_id", "sample_1", "sample_9") SELECT "id", "sample_2", "sample_3", "sample_4", "sample_5", "sample_6", "sample_7", "sample_8", "created_at", "updated_at", "created_by_id", "sample_10_id", "updated_by_id", "sample_1", "sample_9" FROM "app_item__old";
DROP TABLE "app_item__old";
CREATE INDEX "app_item_created_by_id_a8ffed89" ON "app_item" ("created_by_id");
CREATE INDEX "app_item_sample_10_id_c24ee555" ON "app_item" ("sample_10_id");
CREATE INDEX "app_item_updated_by_id_580f5996" ON "app_item" ("updated_by_id");
COMMIT;
参考:Django マイグレーション まとめ - Qiita
models.pyを更新したらアプリが再読み込みされる
こんな表示が出て勝手にリスタートするっぽいんですよねえ。
System check identified no issues (0 silenced). April 18, 2021 - 18:39:55 Django version 2.1.2, using settings 'config.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
するとこんな感じで子プロセスのPIDが変わっていることがわかりました。つまりDjangoはコードが変わると、親プロセスが子プロセスを殺して新しくするということですね。(SIGHUPを送るって書いてあったしな)
% ps -ef |grep runserver |grep -v grep 501 91489 89896 0 6:43PM ttys002 0:00.51 /usr/local/xx/Python manage.py runserver 501 91493 91489 0 6:43PM ttys002 0:01.44 /usr/local/xx/Python manage.py runserver 〜この間にファイルを更新する、プロセス再起動〜 % ps -ef |grep runserver |grep -v grep 501 91489 89896 0 6:43PM ttys002 0:00.51 /usr/local/xx/Python manage.py runserver 501 91520 91489 0 6:43PM ttys002 0:00.32 /usr/local/xx/Python manage.py runserver
ということは、サイドカーでgit-syncを使えば勝手に更新するという機構が作れるということか。いやただググっても情報がたいして出てこないのでrunserverで起動した時だけの話か…。