RailsのデータベースをSQLiteからPostgresqlに変える方法【デイトラ】

  • データベースを「SQlite」から「PostgreSQL」に切り替えたい方
  • PostgreSQLをとりあえず使いたい方
  • Ruby on RailsでWebアプリを制作し始めた方
ケイ
ケイ

こんにちは!
Ruby on Rails学習者のケイ(@new_design)です。

今回はRuby on Rails(以下Rails)のデータベースを「SQlite」(エスキューライト)から「PostgreSQL」(ポストグレスキューエル)に変更する方法を解説していきます。

RailsのデータベースはデフォルトでSQliteに設定されています。しかし実際の開発現場ではPostgresqlが使用されています。

PostgreSQLのインストールから良く起きるエラーの解決策まで説明していきますので、ぜひ参考にしてくださいね。

Potsgresqlをインストールしよう

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という翻訳アプリがおすすめです。

では本題に戻ります。一つずつ順番に問題を整理していきましょう!

STEP1 動いているpostmasterを調べよう

エラー文にある通り、既に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の物が動いていることが確認できました。

STEP2 動いているPIDを止める

では次に今動いている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」が存在しているのが問題らしいです。

STEP3 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を起動するように設定していたからです。設定方法については下記記事で紹介しているので、ぜひ参考にしてください。

【postgreSQL】PG::ConnectionBadの対処方法【デイトラ】
関連記事

Railsを終了させる時は必ず「Control + C」で落とすようにしましょう。

Gemfileの設定を変更

次に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の変更

次に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に切り替えることができました。

サーバーを開いている場合は、一度落としましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です