マイグレーションでカラムの内容を修正する


この記事は、「fukuoka.ex Elixir／Phoenix Advent Calendar 2019」22日目の記事です。
本当は昨日までですが、遅れての投稿です、ごめんなさい。。

最近Elixirの案件に入ってマイグレーションから修正をよくやることがあったので書いておきます。
環境は以下の通りです。

```
$ mix hex.info
Hex:    0.20.1
Elixir: 1.9.2
OTP:    22.1.5

$ mix phx.new -v
Phoenix v1.4.11

```
利用するデータベースはPostgreSQL,MySQLどちらでも構いません、設定済みを前提で進めます。
環境構築をされてない方は[こちら](https://qiita.com/piacerex/items/a7558adc6856e3577dc6)を参照して設定をしておいて下さい。
ここではPostgreSQLを使用します。


例えば以下のようにPhoenixでプロジェクトを作りデータベースまで構築しておきます。



```
$ mix phx.new blog_sample
$ cd blog_sample/
$ mix ecto.create    
$ mix phx.server

```

わざとbodyをstringにしてみます。

```
$ mix phx.gen.html Blog Post posts title:string body:string
$ mix ecto.migrate
```


PostgreSQLのコンソールからテーブルの内容を確認します。



```
blog_sample=# \d posts;
                                          Table "public.posts"
   Column    |              Type              | Collation | Nullable |              Default              
-------------+--------------------------------+-----------+----------+-----------------------------------
 id          | bigint                         |           | not null | nextval('posts_id_seq'::regclass)
 title       | character varying(255)         |           |          | 
 body        | character varying(255)         |           |          | 
 inserted_at | timestamp(0) without time zone |           | not null | 
 updated_at  | timestamp(0) without time zone |           | not null | 
Indexes:
    "posts_pkey" PRIMARY KEY, btree (id)



```

ここで、bodyのstringをtextに修正してみます。

まずectoコマンドでマイグレーションファイルを生成します。
マイグレーションファイルは `処理_カラム名_to_テーブル名` など分かりやすい名前にするのが良いでしょう。

```
$ mix ecto.gen.migration modify_string_in_body_to_posts
```

実行すると `/blog_sample/priv/repo/migrations/` 配下に以下のようにファイルが作られます。

```/blog_sample/priv/repo/migrations/{date}_modify_string_in_body_to_posts.exs
defmodule BlogSample.Repo.Migrations.ModifyStringInBodyToPosts do
  use Ecto.Migration

  def change do

  end
end

```



こんな感じで追記します。

```/blog_sample/priv/repo/migrations/{date}_modify_string_in_body_to_posts.exs
defmodule BlogSample.Repo.Migrations.ModifyStringInBodyToPosts do
  use Ecto.Migration

  def change do
    alter table(:posts) do
    　modify :body, :text
    end
  end
end

```

変更したら、マイグレートを実行します。


```
$ mix ecto.migrate

17:51:23.941 [info]  == Running 20191223084418 BlogSample.Repo.Migrations.ModifyStringInBodyToPosts.change/0 forward

17:51:23.943 [info]  alter table posts

17:51:23.950 [info]  == Migrated 20191223084418 in 0.0s

```



bodyのカラムがtextに変更されたか確認します。

```
blog_sample=# \d posts
                                          Table "public.posts"
   Column    |              Type              | Collation | Nullable |              Default              
-------------+--------------------------------+-----------+----------+-----------------------------------
 id          | bigint                         |           | not null | nextval('posts_id_seq'::regclass)
 title       | character varying(255)         |           |          | 
 body        | text                           |           |          | 
 inserted_at | timestamp(0) without time zone |           | not null | 
 updated_at  | timestamp(0) without time zone |           | not null | 
Indexes:
    "posts_pkey" PRIMARY KEY, btree (id)

```

こんな感じで簡単に変更できます。


他にも
カラムを追加する `add` や
カラム自体を削除する `remove` などもあるので状況に併せて使うことができます。