テーブルをSQLで削除した後にmigrateで再作成されなかった

# 背景
業務でDjangoを使っています。
MySqlで直接テーブルを削除したのですが、migrateしてもテーブルが再作成されなかったです。
それで以下の投稿記事の「マイグレーション管理用のテーブルで履歴を削除すること」で解決しましたが内容を整理します。

https://teratail.com/questions/364332

:::note
このブログの作者はフロントエンドにweightをかけ過ぎている者です😇
温かい目で見守って頂けると助かります
:::

# Model
Model（モデル）は1つのデータベーステーブルにマッピングされます

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
```

first_name と last_name はモデルのフィールドです。
各フィールドはクラス属性として指定され、各属性はデータベースのカラムにマッピングされます。
上記のPersonモデルは以下のようなデータベーステーブル（Mysql）を作成します。

```sql
CREATE TABLE myapp_person (
    `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `first_name` VARCHAR(30) NOT NULL,
    `last_name` VARCHAR(30) NOT NULL
);
```

[models](https://docs.djangoproject.com/en/5.0/topics/db/models/)

# Migration
モデルに加えた変更（フィールドの追加、モデルの削除など）を データベーススキーマに反映させます
## コマンド
### migrate
データベースにマイグレーションの適用と適用解除を行います
```python
python manage.py migrate
```
### makemigrations
モデルに加えた変更に基づいて新しいマイグレーションを作成します
```python
python manage.py makemigrations
```
### sqlmigrate
マイグレーションのSQL文を表示します
```python
python manage.py sqlmigrate
```
以下はサンプルですか、このように表示されるそうです
```python
python manage.py sqlmigrate historical_data 0001
BEGIN;
--
-- Create model PriceHistory
--
CREATE TABLE "historical_data_pricehistory" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "date" datetime NOT NULL,
    "price" decimal NOT NULL,
    "volume" integer unsigned NOT NULL
);
COMMIT;
```

### showmigrations
プロジェクトのマイグレーションとそのステータスを一覧表示します
```python
python manage.py showmigrations
```
### makemigrations
モデルの変更を個々のマイグレーションファイル（コミットに似ています）にパッケージ化します
```python
python manage.py makemigrations
```
[migrations](https://docs.djangoproject.com/en/5.0/topics/migrations/)

# Dependency
マイグレーションクラスの依存関係リストには、このマイグレーションを適用する前に適用しなければならないマイグレーションが含まれます。

# Operation
Modelが過去にどのような状態であったかを調べ、前回のMigration以降でModelに加えた変更を計算し、Migrationファイルを自動的に書くことができます。
マイグレーションを適用すると、各オペレーションは特定のデータベースに必要なSQL文を生成します。

[migration-operations](https://docs.djangoproject.com/en/5.0/ref/migration-operations/)

# django_migrations

Djangoはdjango_migrationsというテーブルをマイグレーション管理用に使います。
Djangoは、最初にマイグレーションを適用するときに、自動的にこのテーブルをデータベースに作成します。
マイグレーションがapplyされたり、 fakeされたりするたびに新しい行がテーブルに挿入されます。

次にマイグレーションが実行されるとき、 django_migrationsテーブルに登録されたマイグレーションをスキップします。
つまり、既に適用されているマイグレーションファイルを手動で変更しても、データベースにそのマイグレーションの履歴がある限り、Djangoはその変更を無視します。

:::note
テーブルから対応するマイグレーション履歴を削除することで、Djangoを騙してマイグレーションを再実行させることもできます。
これはめったに良い考えではなく、マイグレーションシステムが壊れたままになってしまう可能性があります。
:::

# Djangoがモデルの変更を検出する方法
Djangoは適用された全てのマイグレーションを調べ、モデルがどうあるべきかのプロジェクト状態を構築します。
このプロジェクト状態は現在のモデル定義と比較され、適用されるとプロジェクト状態をモデル定義に合わせて最新の状態にする一連の操作のリストが作成されます。

## チェスの例
あなたのモデルをチェスの盤のように考えることができ、Djangoはチェスのグランドマスターとしてあなたの対戦を見守ります。しかし、グランドマスターはあなたの一挙手一投足を見ているわけではありません。グランドマスターが盤を見るのは、あなたが```makemigration```叫ぶときだけです。

可能な手は限られているので（そしてグランドマスターはグランドマスターなので）、彼女は最後に盤面を見てから起こった手を思いつくことができる。彼女はいくつかのメモを取り、あなたが再び```makemigration```の声を上げるまでプレーさせる。

次に盤面を見るとき、グランドマスターは前回のチェス盤がどうなっていたかを覚えていないが、前の手のメモを調べて、チェス盤がどうなっていたかのメンタルモデルを構築することができます。

```migrare```を叫ぶと、グランドマスターは記録されたすべての手を別のチェス盤で再生し、どの記録がすでに適用されているかをスプレッドシートに記録する。この2つ目のチェス盤があなたのデータベースで、スプレッドシートが django_migrationsテーブルです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/22e06620-a2f8-877b-e858-cb453f5f2938.png)

# テーブルをSQLで直接削除してしまった場合にどうすれば良かったのか

```django_migrationsテーブルの履歴を削除してはいけなかった```というのは前の章で述べてますので本来どうするべきだったかを考えます。

https://teratail.com/questions/364332

>マイグレーション地点を戻すためにDROP TABLEを呼ぶ可能性を考えると、テーブルが削除済みなために失敗

上の投稿では[マイグレーションを戻す](https://edocs.djangoproject.com/en/3.2/topics/migrations/#reversing-migrations)ことに失敗していました
以下を考えました

```マイグレーションを戻す前にSQLで削除したテーブルをSQLで直接作成する```
↓
マイグレーションを戻す
↓
テーブルが削除される
↓
django_migrationsテーブルの履歴を操作しないで済む

# 最後に
- Django,バックエンドのことはまださっぱりわからないですが、少しづつ力をつけたいです
- migrationファイルを削除して一つのファイルにまとめたことがありましたがこれも推奨されないことをしていたんだなと痛感しました

# 参考
- [Djangoの概要を掴む](https://qiita.com/yamatai12/items/3bd737f4449c970db273)
- [Digging Deeper Into Django Migrations](https://realpython.com/digging-deeper-into-migrations/)