python django 書籍管理システム開発備忘録 #２（マイグレーション）

前の記事
・[python django 書籍管理システム開発備忘録 #１（開発環境構築）](https://qiita.com/syakesoba/items/45d49e666bc1899bb9ed)

# １．今日の目標
今日はマイグレーションというものをやっていこうと思います。
javaしか触ってこなかったので、マイグレーションというものになじみがなかったのですが
どうやらテーブルを作成する処理？のようです。

下記記事から引用させていただくと

:::note info
アプリケーションで使うデータベースの定義を自動的に作成・管理する機能です。
旧来データベースに接続して直接変更を行っていた作業を、モデルから自動生成されるコードの実行で置き換えます。
:::

https://qiita.com/okoppe8/items/c9f8372d5ac9a9679396

ということだそうです。
モデルに記載するだけでテーブルが作成、変更できるのは楽ですね。
SQLを記載する手間が省けます。
ということで、まずはmodels.pyの記述から。

# ２．models.pyの作成
## １．テーブル定義
models.pyに記載する前にテーブルの攻勢を考えておきます。
試しにdjangoを使って開発をすることが目的なのでそこまで深くは考えません。

とりあえず、パッと思いついた本棚管理システムに最低限必要な情報は以下
・作品名
・著者
・ジャンル

この情報を元にテーブルを定義していく。

上記の情報をもとにテーブルを考えると
まず、作品テーブル

#### 作品テーブル
| カラム名 | 型 | 制約 |
|:-|:-|:-|
| 作品id | serial | pkey |
| 作品名 | character varying |  |
| 著者  | character varying |  |
| ジャンル | character varying |  |
| 登録日時 | timestamp |  |
| 変更日時 | timestamp |  |
| 削除日時 | timestamp | null OK |

こんな感じ？
ただ、著者やジャンルも管理して、その中から作品登録時に
セレクトボックスとかで選択するような形にしたいため

著者とジャンルは別テーブルで管理する。
そのため、下記のようなテーブル構成にする。
#### 作品テーブル
| カラム名 | 型 | 制約 |
|:-|:-|:-|
| 作品id | serial | pkey |
| 作品名 | character varying |  |
| 著者id  | integer |  |
| ジャンルid | integer |  |
| 登録日時 | timestamp |  |
| 変更日時 | timestamp |  |
| 削除日時 | timestamp | null OK |
#### 著者テーブル
| カラム名 | 型 | 制約 |
|:-|:-|:-|
| 著者id | serial | pkey |
| 著者名 | character varying |  |
| 登録日時 | timestamp |  |
| 変更日時 | timestamp |  |
| 削除日時 | timestamp | null OK |
#### ジャンルテーブル
| カラム名 | 型 | 制約 |
|:-|:-|:-|
| ジャンルid | serial | pkey |
| ジャンル名 | character varying |  |
| 登録日時 | timestamp |  |
| 変更日時 | timestamp |  |
| 削除日時 | timestamp | null OK |

こんな感じに分けて、それぞれを管理する形にします。
テーブル定義こんな感じ。

## ２．models.pyの記述
上記のテーブル定義を元にmodels.pyを記載してみましょう。
実際に書いたのはこんな感じ
```python
from django.db import models

# Create your models here.

# 作品テーブル
class Book(models.Model):
    book_id = models.AutoField(primary_key=True)
    author_id = models.IntegerField()
    genre_id = models.IntegerField()
    title = models.CharField()
    add_datetime = models.DateTimeField()
    update_datetime = models.DateTimeField()
    delete_datetime = models.DateTimeField(null=True)

    def __str__(self):
        return self.title

# 著者テーブル
class Author(models.Model):
    author_id = models.AutoField(primary_key=True)
    author = models.CharField()
    add_datetime = models.DateTimeField()
    update_datetime = models.DateTimeField()
    delete_datetime = models.DateTimeField(null=True)

    def __str__(self):
        return self.author

# ジャンルテーブル
class Genre(models.Model):
    genre_id = models.AutoField(primary_key=True)
    genre = models.CharField()
    add_datetime = models.DateTimeField()
    update_datetime = models.DateTimeField()
    delete_datetime = models.DateTimeField(null=True)

    def __str__(self):
        return self.genre
```
カラムの型に関しては、以下の記事を参考

https://qiita.com/uenosy/items/f2de5c02f2e468b62915

ちなみに
```python
    def __str__(self):
        return self.title
```
この記述は何なのか？

下記の記事を参照すると、どうやらdjango特有の管理画面があるようで
そこでのカラムに何を表示させるのかを設定するもののようです。

https://qiita.com/1999-07-08/items/17f0b97d56325b6a0edb

なので別に記載しなければならないものでもなさそう。

## ３．マイグレーション
さぁ今回のメインであるマイグレーションです。
手順自体は簡単。コマンドを打つだけ。

まず、マイグレーションファイルなるものを作成するそうです。
コマンドは以下
```
python manage.py makemigrations 自身のapp名
```
私の場合は
```
python manage.py makemigrations django_app
```
こんな感じ。

ちなみにマイグレーションファイルとは何かというと
記事のはじめでも参照した、下記の記事においては

:::note info
model.pyの内容をデータベースに反映させるための中間ファイル。
makemigrationsコマンドで作成する。
初回のデータと、それにつらなる一連の差分データで構成されます。
:::

https://qiita.com/okoppe8/items/c9f8372d5ac9a9679396

こんな感じの説明。
まぁマイグレーションを行う際に必要となるファイルですかね。
のちのち詳しいことも調べていきたいと思います。

そして、ついにマイグレーションの実行
コマンドは以下
```
python manage.py migrate
```
これによりDBにテーブルが作成されます。
これにて終了。

マイグレーション自体はあっけなかったですね。
次回はDBから値をとる処理やそれに伴い一覧画面の実装をしていきたいと思います。

# その他
githubにソースは載せてあります。

https://github.com/syakesoba/django_project

前の記事
・[python django 書籍管理システム開発備忘録 #１（開発環境構築）](https://qiita.com/syakesoba/items/45d49e666bc1899bb9ed)