Djangoのチュートリアルをなぞってみる その3:データベース
前回のスクラップの続き
Django公式チュートリアルをなぞっています。
以下のページからです。
DBの接続設定はmysite/settings.py
に書いてある。
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
mysite/settings.py
にある以下の記述は、Djangoのこのprojectに初めからインストールされているappがリストしてある。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
このappの中にはDBのテーブルを必要とするものがある。SQLiteのファイルは0バイトの状態で存在している。
$ ll db.sqlite3
-rw-r--r-- 1 ubuntu ubuntu 0 2023-08-05 10:37:42 db.sqlite3
以下のコマンドで、各appが必要とするテーブル作成をする。
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
$ ll db.sqlite3
-rw-r--r-- 1 ubuntu ubuntu 131072 2023-08-05 12:45:34 db.sqlite3
sqlite3
コマンドをUbuntu 22.04にインストールしてみる。
$ sudo apt install -y sqlite3
$ sqlite3 --version
3.40.1 2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f3alt1
SQLiteに作成されたテーブルを見てみる。
$ sqlite3 db.sqlite3
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> .tables
auth_group auth_user_user_permissions
auth_group_permissions django_admin_log
auth_permission django_content_type
auth_user django_migrations
auth_user_groups django_session
テーブルの中身。ほとんどはまだレコードが1つもないが一部のテーブルはレコードが存在する。
sqlite> select * from auth_group;
sqlite> select * from auth_user;
sqlite> select * from django_admin_log;
sqlite> select * from django_content_type;
1|admin|logentry
2|auth|permission
3|auth|group
4|auth|user
5|contenttypes|contenttype
6|sessions|session
sqlite> select * from django_migrations;
1|contenttypes|0001_initial|2023-08-05 03:45:34.406722
2|auth|0001_initial|2023-08-05 03:45:34.438475
3|admin|0001_initial|2023-08-05 03:45:34.472886
4|admin|0002_logentry_remove_auto_add|2023-08-05 03:45:34.487529
5|admin|0003_logentry_add_action_flag_choices|2023-08-05 03:45:34.501505
6|contenttypes|0002_remove_content_type_name|2023-08-05 03:45:34.519439
7|auth|0002_alter_permission_name_max_length|2023-08-05 03:45:34.535129
8|auth|0003_alter_user_email_max_length|2023-08-05 03:45:34.549934
9|auth|0004_alter_user_username_opts|2023-08-05 03:45:34.564350
10|auth|0005_alter_user_last_login_null|2023-08-05 03:45:34.578646
11|auth|0006_require_contenttypes_0002|2023-08-05 03:45:34.589921
12|auth|0007_alter_validators_add_error_messages|2023-08-05 03:45:34.601402
13|auth|0008_alter_user_username_max_length|2023-08-05 03:45:34.615729
14|auth|0009_alter_user_last_name_max_length|2023-08-05 03:45:34.629335
15|auth|0010_alter_group_name_max_length|2023-08-05 03:45:34.646827
16|auth|0011_update_proxy_permissions|2023-08-05 03:45:34.659136
17|auth|0012_alter_user_first_name_max_length|2023-08-05 03:45:34.672031
18|sessions|0001_initial|2023-08-05 03:45:34.695287
sqlite> select * from django_session;
モデルを作る。次のように編集する。
diff --git a/mysite/mysite/settings.py b/mysite/mysite/settings.py
index 96f9eca..1a08a1b 100644
--- a/mysite/mysite/settings.py
+++ b/mysite/mysite/settings.py
@@ -37,6 +37,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'polls.apps.PollsConfig',
]
MIDDLEWARE = [
diff --git a/mysite/polls/models.py b/mysite/polls/models.py
index 71a8362..dc981e8 100644
--- a/mysite/polls/models.py
+++ b/mysite/polls/models.py
@@ -1,3 +1,10 @@
from django.db import models
-# Create your models here.
+class Question(models.Model):
+ question_text = models.CharField(max_length=200)
+ pub_date = models.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)
polls/apps.py
に PollsConfig
クラスが定義してある。settings.py
にある'polls.apps.PollsConfig'
とはこれのことだろう。
from django.apps import AppConfig
class PollsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'polls'
python manage.py makemigrations polls
コマンドでマイグレーションスクリプトを作成。python manage.py migrate
の前にこれをやらないといけないのか。
$ python manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
Pythonスクリプトが1つ生成される。
# Generated by Django 4.2.4 on 2023-08-05 04:12
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Question',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question_text', models.CharField(max_length=200)),
('pub_date', models.DateTimeField(verbose_name='date published')),
],
),
migrations.CreateModel(
name='Choice',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('choice_text', models.CharField(max_length=200)),
('votes', models.IntegerField(default=0)),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.question')),
],
),
]
テーブルにはid
カラムが勝手にできるようだ。
マイグレーションスクリプトを実行する。
$ python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" bigint NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
何番のマイグレーションまで実行済みかのステータスは保持していないのだろうか。。。
python manage.py sqlmigrate
コマンドはSQLを表示するだけで、SQLiteへの実際の変更処理は行わない。プレビュー目的。だからステータスは関係なかった。
実際に変更処理するには以下のコマンド。
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
マイグレーションのステータスはdjango_migrations
テーブルに保存されているようだ。
$ sqlite3 db.sqlite3
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> select * from django_migrations;
1|contenttypes|0001_initial|2023-08-05 03:45:34.406722
2|auth|0001_initial|2023-08-05 03:45:34.438475
3|admin|0001_initial|2023-08-05 03:45:34.472886
4|admin|0002_logentry_remove_auto_add|2023-08-05 03:45:34.487529
5|admin|0003_logentry_add_action_flag_choices|2023-08-05 03:45:34.501505
6|contenttypes|0002_remove_content_type_name|2023-08-05 03:45:34.519439
7|auth|0002_alter_permission_name_max_length|2023-08-05 03:45:34.535129
8|auth|0003_alter_user_email_max_length|2023-08-05 03:45:34.549934
9|auth|0004_alter_user_username_opts|2023-08-05 03:45:34.564350
10|auth|0005_alter_user_last_login_null|2023-08-05 03:45:34.578646
11|auth|0006_require_contenttypes_0002|2023-08-05 03:45:34.589921
12|auth|0007_alter_validators_add_error_messages|2023-08-05 03:45:34.601402
13|auth|0008_alter_user_username_max_length|2023-08-05 03:45:34.615729
14|auth|0009_alter_user_last_name_max_length|2023-08-05 03:45:34.629335
15|auth|0010_alter_group_name_max_length|2023-08-05 03:45:34.646827
16|auth|0011_update_proxy_permissions|2023-08-05 03:45:34.659136
17|auth|0012_alter_user_first_name_max_length|2023-08-05 03:45:34.672031
18|sessions|0001_initial|2023-08-05 03:45:34.695287
19|polls|0001_initial|2023-08-05 06:13:45.283897
テーブルが増えていた。
$ sqlite3 db.sqlite3
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> .tables
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups polls_choice
auth_user_user_permissions polls_question
Pythonでモデルを定義してからDBのテーブルに反映するまでの流れ
python manage.py makemigrations polls
python manage.py sqlmigrate polls 0001
python manage.py migrate