- データベースを「SQlite」から「PostgreSQL」に切り替えたい方
- PostgreSQLをとりあえず使いたい方
- Ruby on RailsでWebアプリを制作し始めた方
今回はRuby on Rails(以下Rails)のデータベースを「SQlite」(エスキューライト)から「PostgreSQL」(ポストグレスキューエル)に変更する方法を解説していきます。
RailsのデータベースはデフォルトでSQliteに設定されています。しかし実際の開発現場ではPostgresqlが使用されています。
PostgreSQLのインストールから良く起きるエラーの解決策まで説明していきますので、ぜひ参考にしてくださいね。
Contents
STEP1 Postgresqlをインストール
PostgreSQLを使うにはまずインストールする必要があります。まずはターミナルを開いて下記コマンドを実行してください。
過去にインストールしている場合は実行する必要はありません。
$brew install postgresql
ちゃんとインストールできているか確認するために下記コマンドを実行してください。
$postgres --version
STEP2 postgreSQLを初期化
次にpostgreSQLを初期化するために下記コマンドを実行してください。
$initdb /usr/local/var/postgres -E utf8
STEP3 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を起動できないよ」という意味です。
余談ですが、もし英語に不安がある方はDeeplという翻訳アプリがおすすめです。
では本題に戻ります。一つずつ順番に問題を整理していきましょう!
エラー文にある通り、既にpostmasterというものが動いているらしいので、詳細をみてみたいですね。そこでターミナルで次のコマンドを入力してみましょう。
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の物が動いていることが確認できました。
では次に今動いているPID499を止めてみましょう。
下記コマンドをターミナルで入力してください。今回は「499」でしたが皆さんの環境によって変わりますので、「ps aux | grep postgresql」で確認ください。
$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
下画像のようにログが返ってきます。
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
STEP4 エラーが出た原因を考えよう
今回エラーが出た原因は、postgreSQLを正しく終了させていないためpostmaster.pidが残っていたことが原因です。
起動時にエラーが出る場合はほぼこれが原因と考えて良いでしょう。
自分の場合はパソコン起動時にpostgresqlを起動するように設定していたからです。設定方法については下記記事で紹介しているので、ぜひ参考にしてください。
Railsを終了させる時は必ず「Control + C」で落とすようにしましょう。
次にGemfileの設定を変える必要があります。
なぜならRailsのデータベースはデフォルトでSQliteに設定されているので、PostgreSQLに変えてあげる必要があるからです。
まずはGem.fileを開きます。
そうすると下記のようにsqliteの部分を見つけることができるので、削除してみましょう。
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
代わりに下記内容を貼り付けてください。
gem 'pg', '>= 0.18', '<2.0'
gem.fileの変更は以上です。できたら次の章に進みましょう。
次に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
$rails db:seed
お疲れ様です!これでRailsのデータベースをpostgreSQLに切り替えることができました。
サーバーを開いている場合は、一度落としましょう。
これまでデフォルトで設定されているSQliteをPostgreSQLに変更する方法を解説してきました。
別の方法として、rails newする際にデータベースをPostgreSQLで指定することもできます。
rails new アプリ名 -d postgresql
こうすることで、database.ymlなどの編集も必要ないので楽ですね。
コメントを残す