Djangoチュートリアル (2) モデル
mysite/settings.py を眺める
データベースやアプリの設定があるけど今はいじらなくてよい
データベースをマイグレートする
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK
$ ls
db.sqlite3 manage.py mysite polls
sqlite3のファイルができてる
$ sqlite3 db.sqlite3
sqlite> .schema
CREATE TABLE IF NOT EXISTS "django_migrations" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" datetime NOT NULL);
CREATE TABLE sqlite_sequence(name,seq);
...
CREATE INDEX "django_session_expire_date_a5c62663" ON "django_session" ("expire_date");
sqlite> .quite
モデルの作成
モデルは、手持ちのデータに対する唯一の決定的なソースです。 ... Django のモデルの目的は、ただ一つの場所でデータモデルを定義し、そこから自動的に色々なものを派生させることにあります。
マイグレーションは完全にモデルのファイルから生成されます。
polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = medels.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
Field インスタンスそれぞれの名前(例: question_text や pub_date)は、機械可読なフィールド名です。このフィールド名はPythonコードで使うとともに、データベースも列の名前として使うことになります。
このへん、どういう仕組みになってんだろうね
さっきやった、マイグレートの作業のときになにかやってるんだろうけど
Field の最初の位置引数には、オプションとして人間可読なフィールド名も指定できます。このフィールド名は Django の二つの内省機能で使う他、ドキュメントとしての役割も果たします。
内省ってのはリフレクションの訳かな
用語としてそういう訳し方もある?
確かに内省と言えなくもない
mysite/settings.pyにpollsアプリが追加されたことを反映する
さっきURLを追加したけどあれだけじゃ足りないのか
INSTALLED_APPS = [
'polls.apps.PollsConfig', #ここ
'django.contrib.admin',
...
'django.contrib.staticfiles',
]
そしてマイグレーションを作成
マイグレーションマイグレーション言うけどマイグレーションとは何か
$ python manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Choice
- Create model Question
- Add field question to choice
polls/migrations/0001_initial.py というファイルができてて
中身はもっと生っぽいスキーマ定義のコード
これを実行するとスキーマが定義されるんだろう
sqlmigrateというサブコマンドでSQLにして見ることができるらしい
$ python manage.py sqlmigrate polls 0001
BEGIN;
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL);
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
ALTER TABLE "polls_choice" RENAME TO "polls_choice__old";
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id"));
INSERT INTO "polls_choice" ("id", "choice_text", "votes", "question_id") SELECT "id", "choice_text", "votes", NULL FROM "polls_choice__old";
DROP TABLE "polls_choice__old";
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
なるほど
だいたいわかった
これでmigrate
すると新たなテーブルができる
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
マイグレーションはとても強力なツールであり、プロジェクトの発展に合わせて、モデルを変更し続けていくことができます。データベースやテーブルを削除して作り直す必要はありません - マイグレーションは、データを失うことなしにデータベースをライブでアップグレードするよう特化しています。
model.pyを変更したらmakemigrationsしてmigrateする
モデルを変更したらマイグレーションを作ってマイグレートする
次はデータベースに差分を適用するコードが0002の下にできるんだろうな
だいたいわかった
マイグレーションの作成と適用のコマンドが分割されている理由は、マイグレーションをバージョン管理システムにコミットし、アプリとともに配布するためです。
なんかそういうの聞いたことある
Database as Codeだったか
スキーマ変更をロールバックするスクリプトもできてたりするのかな