フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

Djangoのサンプル動かして気になる点を調査した

f:id:lirlia:20210418121750p:plain

今回とりあえず触ったのはこちらの手順。ありがとうございます。

qiita.com

データベースのマイグレーション

コードのModelの情報に従ってデータベースのマイグレーションをしてくれるコードですね。

python3 manage.py migration

これに合わせてテーブルが作成されたり、消されたり、カラム操作が行われます。そう考えるとひじょーーーに怖いです。本番環境でデータベースをよしなに操作してくれるって怖さしかないです。

というかそもそもデータベースのマイグレーションって一般的なの?っていうところから調べるました。するとこの記事がヒット。

mrasu.hatenablog.jp

いろんな理由がありますがマイグレは一般的なこと。ただし実施する際に様々な観点を考慮する必要があるとのこと。(そりゃそうだ)

おまけ:社内DBマイグレーションルール - Qiita


実際にカラムを消すように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で起動した時だけの話か…。