【rails7】SQLite → postgreSQL に移行する

開発の途中でデータベースを変える

今後、本番=Postgres 予定なら最初から Postgresにしておくこと。

前提
  • 開発環境であること
  • 既存データは捨てても構わないこと

ActiveStorage は DB 切替にそのまま追従する


PostgreSQL を入れる & 起動

以下を順番に実行

brew install postgresql@14
brew services start postgresql@14

# psql が見つからない場合
echo 'export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"' >> ~/.zshrc && exec $SHELL


Gem を切り替える

Gemfileを書き換える

# 使わない場合はコメントアウト/削除
# gem 'sqlite3', '~> 1.4'

# 追加
gem 'pg', '~> 1.5'

実行

bundle install


database.yml を Postgres 用にする

config/database.ymlを書き換える

default: &default
...

development:
  <<: *default
  database: ...

test:
  <<: *default
  database: ...

production:
  <<: *default
...


DB 作成 & マイグレーション

bin/rails db:drop db:create db:migrate


動作確認

新規登録/ログイン/Topic作成/ActiveStorageアップロード の動作をチェック

bin/rails s


Postgres にアプリ用 DB ユーザーを作りたい?

作るなら↓を実行する

# 既にあれば不要。macのデフォは postgres ユーザー

createuser -s postgres

「アプリ用 DB ユーザー」は次↓のときに“作るべき”

  • 本番/ステージング運用
    事故や侵入時の被害を最小化したい(最小権限の原則)。
  • 複数アプリや開発者が同じクラスタを使う
    権限やスキーマを分けたい。
  • 資格情報の管理・ローテーションをしたい
    アプリごとにユーザーを分けておくと、漏えい時の切り離しが簡単。
  • 監査/可観測性
    どのアプリが何をしたかをログで切り分けたい。

作らなくていいのは↓のとき

  • ローカルの試行・学習用で、DB を壊しても困らない。
  • CI の使い捨て DB(毎回初期化される)など、リスクが極小。

切り替え中のエラー

DB 作成 & マイグレーションの段階でエラーが発生

Postgres に postgres というユーザーが存在しない

bin/rails db:drop db:create db:migrate

# => PG::ConnectionBad: connection to server at "::1", port 5432 failed: FATAL: role "postgres" does not exist

Postgres のユーザーを確認

psql -U postgres

# => failed: FATAL:  role "postgres" does not exist

↑デフォルトユーザーが作られていない、というエラーが出る


学習用の場合

まず現状、psql(Postgres のコンソール)に入れるか確認する

psql -d postgres

psqlに入れると↓のようにプロンプトが変わる

psql (15.x)
Type "help" for help.

postgres=#

上記で入れたなら、psqlのusernameは自分のmacOSユーザー名となる


環境変数を設定する

Gemfileに追加する

gem "dotenv-rails", groups: [:development, :test]

.envのファイルをプロジェクト直下に作成

database.ymlに書けないデータをここに書いておく

「username:」=「自分のmacOSユーザー名」


あらためてPostgresに移行する

bin/rails db:drop db:create db:migrate

エラーが出なければ移行完了


【.gitignore】必ず確認すること

  • config/master.key が入っているか
    →Railsの秘密鍵は絶対に公開NG。
  • /.env*が入っているか
    →「.env」「.env.development」「.env.production」「.env.local」「.env.staging」 など、全部Git管理から外す