CodeBox CodeBox

RailsのデータベースをSQLiteからPostgresqlに切り替える方法

Ruby / Rails
けい

本記事の内容

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に切り替わりました。お疲れ様です。

ABOUT ME

けい
ベンチャーのフロントエンジニア。 主にVueとTypescriptを使っています。ライターのための文字数カウントアプリ:https://easy-count.vercel.app/