本記事の内容
RailsのデータベースはデフォルトでSQliteに設定されていますが、実際の開発現場ではSQliteは使用されることは少ないです。今回はRailsのデータベースをSQliteからpostgreSQLに変更する方法を解説していきます。
新規アプリ作成する場合
まずは新しくアプリを作成する段階で、データベースをpostgreSQLにする方法を紹介します。方法は簡単で、下記コマンドを実行するだけです。
rails new アプリ名 -d postgresql
既にアプリを作成している場合
次に既に作成したアプリのデータベースをSQliteからpostgreSQLに切り替える方法を解説していきます。
①postgreSQLをインストール
まずpostgreSQLをインストールする必要があります。まずはターミナルを開いて下記コマンドを実行してください。(過去にインストールしている場合は実行する必要はありません。)
> brew install postgresql
下記コマンドでインストールされたか確認します。
> postgres --version
②postgreSQLを初期化
次にpostgreSQLを初期化するために下記コマンドを実行します。
> initdb /usr/local/var/postgres -E utf8
③postgreSQLを起動
実際にpostgreSQLを起動します。
> pg_ctl start -D /usr/local/var/postgres
コマンド実行して下画面のようになれば成功です。
waiting for server to start....2020-10-10 14:49:57.731 JST [5974] LOG: starting PostgreSQL 12.4 on x86_64-apple-darwin19.5.0, compiled by Apple clang version 11.0.3 (clang-1103.0.32.62), 64-bit
2020-10-10 14:49:57.732 JST [5974] LOG: listening on IPv6 address "::1", port 5432
2020-10-10 14:49:57.733 JST [5974] LOG: listening on IPv4 address "127.0.0.1", port 5432
2020-10-10 14:49:57.734 JST [5974] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2020-10-10 14:49:57.783 JST [5975] LOG: database system was shut down at 2020-10-10 14:38:27 JST
2020-10-10 14:49:57.790 JST [5974] LOG: database system is ready to accept connections
done
server started
起動時にエラーが出た場合の対処方法
postgreSQLを起動させると下画面のようになった方もいるのではないでしょうか?
pg_ctl: another server might be running; trying to start
server anyway waiting for server to start....2020-10-10
14:06:45.145 JST [3869] FATAL: lock file "postmaster.pid" already exists
2020-10-10 14:06:45.145 JST [3869]
HINT: Is another postmaster (PID 499) running in data
directory "/usr/local/var/postgres"?stopped waiting
pg_ctl: could not start server
Examine the log output.
エラー文の内容としては、「既に他のpostmasterが動いているからpostgresqlを起動できないよ」という意味です。1つずつ順番に問題を整理していきましょう!
①動いているpostmasterを調べよう
既にpostmasterというものが動いているらしいので、ターミナルで次のコマンドを入力してみましょう。ps auxコマンドはシステムが動いているか確認するものです。
> ps aux | grep postgresql
次のような結果が得られます。数字は皆さんの環境によって内容は変わります。
499 0.0 0.1 4484680 11840 ?? S 11:27AM
0:00.10 /usr/local/opt/postgresql/bin/postgres -D /usr/local/var/postgres
3892 0.0 0.0 4278524 700 s000 S+ 2:13PM 0:00.01 grep postgresql
先程エラー文にあったPID番号が499の物が動いていることが確認できました。499はプロセス番号と呼ばれて、皆さんの環境によって変わります。
② 動いているPIDを止める
次に動いているPID499を止めるために、下記コマンドをターミナルで入力してください。
$kill -9 499
PID499が止まったか確認するために、下記コマンドで状況を確認してみましょう。
ps aux | grep postgresql
実行後の画面が次の通りです。
3927 0.0 0.0 4268284 676 s000 S+ 2:22PM 0:00.00 grep postgresql
3918 0.0 0.2 4475464 15552 ?? S 2:22PM 0:00.06
/usr/local/opt/postgresql/bin/postgres -D /usr/local/var/postgres
先程のPID499が無くなり表示が変わりました。しかし別のPID番号の物が動いていますね。postgreSQL起動時のログを確認するために、次のコマンドを入力します。
> tail /usr/local/var/postgres/server.log
下画像のようにログが返ってきます。既に「postmaster.pid」が存在しているのが問題らしいです。
2020-09-14 14:45:39.582 JST [71593] FATAL: lock file "postmaster.pid" already exists
2020-09-14 14:45:39.582 JST [71593] HINT: Is another postmaster (PID 71564) running in data directory "/usr/local/var/postgres"?
③postmaster.pidを削除
次にpostmaster.pidを削除するために、次のコマンドを実行していきましょう。
> rm /usr/local/var/postgres/postmaster.pid
> launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
> launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
> ps aux | grep postgres
これでPostgresqlが起動しました!
3991 0.0 0.0 4277500 696 s000 S+ 2:27PM 0:00.01 grep postgres
3989 0.0 0.0 4484588 1672 ?? Ss 2:27PM 0:00.00 postgres: logical replication launcher
3988 0.0 0.0 4338792 908 ?? Ss 2:27PM 0:00.00 postgres: stats collector
3987 0.0 0.0 4484588 1908 ?? Ss 2:27PM 0:00.00 postgres: autovacuum launcher
3986 0.0 0.0 4484396 1072 ?? Ss 2:27PM 0:00.00 postgres: walwriter
3985 0.0 0.0 4484396 1096 ?? Ss 2:27PM 0:00.00 postgres: background writer
3984 0.0 0.0 4484396 1044 ?? Ss 2:27PM 0:00.00 postgres: checkpointer
3982 0.0 0.2 4484680 15620 ?? S 2:27PM 0:00.05 /usr/local/opt/postgresql/bin/postgres -D /usr/local/var/postgres
ちなみにpostgresqlが動いているかどうかは、先程から紹介している下記コマンドを実行すれば分かります。
$ps aux | grep postgresql
postgresqlが動いていなければ下記のような表示になります。
5879 0.0 0.0 4268284 672 s000 S+ 2:38PM 0:00.00 grep postgres
④エラーが出た原因を考えよう
今回エラーが出た原因は、postgreSQLを正しく終了させていないためpostmaster.pidが残っていたことが原因です。自分の場合はパソコン起動時にpostgresqlを起動するように設定していたからです。
Railsを終了させる時は必ず「Control + C」で落とすようにしましょう。
Gemfileの設定を変更
次にGemfileの設定を変える必要があります。RailsのデータベースはデフォルトでSQliteに設定されているので、PostgreSQLに変えてあげる必要があるからです。
まずはGem.fileを開きます。下記のようにsqliteの部分を削除してください。
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
代わりに下記内容を貼り付けてください。pgというのはpostgreSQLという意味です。
gem 'pg', '>= 0.18', '<2.0'
database.ymlの内容を変更
次にdatabase.ymlの内容を変更します。デフォルトではsqliteの設定が書かれているはずなので、全て削除して下記コードを貼り付けてください。
注意点としては、アプリケーションの名前は皆さんが作成したアプリ名にしてください。僕の場合は「todoappdemo」としています。
# データベースをSQliteからPostgresqlに変更
default: &default
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: todoappdemo_development
test:
<<: *default
database: todoappdemo_test
production:
<<: *default
database: todoappdemo_production
username: todoappdemo
password: <%= ENV['DATABASE_PASSWORD'] %>
host: <%= ENV['DATABASE_HOST'] %>
最後にターミナルで下記コマンドを実行します。
> rails db:create
> rails db:migrate
これでデータベースがpostgreSQLに切り替わりました。お疲れ様です。