【備忘録】【Rails】PostgreSQLインストールからデータベース作成までの流れ

今までMySQLを使用していましたが業務でPostgreSQLを使用することとなり、ローカルにインストールするも、データベース作成時点で何度もエラーになり苦労したので成功したときの流れを備忘録に残しておきます。

# 事前準備

#### ①config/database.yml の編集
database.ymlのdevelopmentを以下のように編集しておきます。

```ruby:database.yml
(省略)

development:
  <<: *default
  database: データベース名
  host: localhost
  port: 5432

(省略)
```

▼参考にさせていただいた記事▼

https://qiita.com/right1121/items/e247c7a52a000ff593d6

#### ②.env の編集

筆者の場合は仕事のプロジェクトでdatabase.ymlのdefault環境のusername、passwordに対して、環境変数を使用しています。
そのため.envファイルを作成し、これから作りたいデータベースのusername、passwordを事前に入力を済ませておきます。
（※このあたりは適宜ご自身の状況に合わせて変更してください）


# インストール〜データベース作成まで


インストール、アンイストールともにHomebrewを使用します。

```ruby:ターミナル
brew install postgresql@13 ←バージョン指定しない場合は最新バージョンがインストールされます。
```

```ruby:結果
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
Updated 1 formula.
==> Updated Casks
Updated 6 casks.

==> Downloading https://ghcr.io/v2/homebrew/core/postgresql/13/manifests/13.4
Already downloaded: /Users/ユーザー名/Library/Caches/Homebrew/downloads/9108fa3f85714f66e41fef926869408b2818a5765bcc36779c2f91bcad57705a--postgresql@13-13.4.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/postgresql/13/blobs/sha256:e9c8001d59522349069422a196365fbfd79706c4abdcac970adf6a60b01aa82b
Already downloaded: /Users/ユーザー名/Library/Caches/Homebrew/downloads/ffdbdb34a34e20e4f0669d92b0e17fff879b302c848d31b11b01646fb798100e--postgresql@13--13.4.catalina.bottle.tar.gz
==> Pouring postgresql@13--13.4.catalina.bottle.tar.gz
==> Caveats
This formula has created a default database cluster with:
  initdb --locale=C -E UTF-8 /usr/local/var/postgresql@13
For more details, read:
  https://www.postgresql.org/docs/13/app-initdb.html

postgresql@13 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have postgresql@13 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/postgresql@13/bin:$PATH"' >> ~/.zshrc

For compilers to find postgresql@13 you may need to set:
  export LDFLAGS="-L/usr/local/opt/postgresql@13/lib"
  export CPPFLAGS="-I/usr/local/opt/postgresql@13/include"

For pkg-config to find postgresql@13 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/postgresql@13/lib/pkgconfig"


To start postgresql@13:
  brew services start postgresql@13
Or, if you don't want/need a background service you can just run:
  /usr/local/opt/postgresql@13/bin/postgres -D /usr/local/var/postgresql@13
==> Summary
🍺  /usr/local/Cellar/postgresql@13/13.4: 3,230 files, 42.8MB
```

返ってきた文章の通り、下記実行。

```ruby:ターミナル
initdb --locale=C -E UTF-8 /usr/local/var/postgresql@13
```
すると、下記エラーが返ってくる。

```ruby:結果
The files belonging to this database system will be owned by user "ユーザー名".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

initdb: error: directory "/usr/local/var/postgresql@13" exists but is not empty
If you want to create a new database system, either remove or empty
the directory "/usr/local/var/postgresql@13" or run initdb
with an argument other than "/usr/local/var/postgresql@13".
```

エラー文の通りに、下記実行。

```ruby:ターミナル
rm -rf /usr/local/var/postgresql@13
```

再度下記実行。

```ruby:ターミナル
initdb --locale=C -E UTF-8 /usr/local/var/postgresql@13
```

```ruby:結果
The files belonging to this database system will be owned by user "ユーザー名".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /usr/local/var/postgresql@13 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D '/usr/local/var/postgresql@13' -l logfile start
```
成功!
末尾に「次のようにしてデータベースサーバを起動することができます。」と書かれているので、起動コマンドをメモしておきましょう。

#### 起動コマンド

```ruby:ターミナル
pg_ctl -D '/usr/local/var/postgresql@13' -l logfile start
```
#### 終了コマンド
```ruby:ターミナル
pg_ctl -D '/usr/local/var/postgresql@13' -l logfile start
```

念の為インストールしたバージョンを確認します。

```ruby:ターミナル
psql --version
```

```ruby:結果
psql (PostgreSQL) 13.4
```

次に、pgAdmin4をインストールします。
pgAdmin4とは、DBにどのようなデータが格納されているかを視覚的に確認しやすくするツールのひとつです。

```ruby:ターミナル
brew install pgadmin4
```

```ruby:結果
==> Downloading https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v6.0/macos/pgadmin4-6.0.dmg
######################################################################## 100.0%
==> Installing Cask pgadmin4
==> Moving App 'pgAdmin 4.app' to '/Applications/pgAdmin 4.app'
🍺  pgadmin4 was successfully installed!
```

成功しました。

では、先程メモしておいたコマンドを打ってDBサーバを起動しましょう。

```ruby:ターミナル
pg_ctl -D '/usr/local/var/postgresql@13' -l logfile start
```

```ruby:結果
waiting for server to start.... done
server started
```

任意の名前のPostgreSQL用のユーザを作ります。

```ruby:ターミナル
createuser -P 任意のユーザー名

Enter password for new role:パスワードを任意入力（パスワードつけたくない場合はEnterのみ）
Enter it again:パスワードを再度入力（パスワードつけたくない場合はEnterのみ）
```

今あるデータベースを確認します。

```ruby:ターミナル
psql -l
```

![スクリーンショット 2021-10-17 17.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/61c4c90b-69a8-24b4-aaa5-eda9f7feded3.png)

「postgres」という名前のデータベースがあるはずです。
下記コマンドで、そこに接続します。

```ruby:ターミナル
psql -d postgres

psql (13.4)
Type "help" for help.

postgres=#
```

「postgres」に接続した状態で、下記コマンドを実行。
Role nameの欄に、ユーザー一覧が表示されています。
この中に、先程作成した任意のユーザー名が存在しているはずです。

```ruby:postgresの中
postgres=# \du
```

![スクリーンショット 2021-10-17 17.29.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/85eb5d24-5665-daf5-2ff3-186168c6b6bd.png)


このユーザーでデータベースを作成するために、下記コマンドでデータベース作成権限を付与します。

```ruby:postgresの中
postgres=# ALTER ROLE ユーザー名 CREATEDB;
ALTER ROLE
```

ちゃんと権限が付与できたか確認してみます。

```ruby:postgresの中
postgres=# \du
```

黄色の枠線の中に注目してください。
ちゃんとデータベース作成権限が付与されていますね。

![スクリーンショット 2021-10-17 17.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/e3785e51-cd3d-70fd-712b-1b2892736b54.png)


これでデータベースを作成する準備が整いました。

ターミナルで下記実行します。

```ruby:ターミナル
bin/rails db:create
```

すると下記エラーが返ってきました。

```ruby:結果
dyld: lazy symbol binding failed: Symbol not found: _PQresultMemorySize
  Referenced from: /Users/ユーザー名/project/プロジェクト名/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg_ext.bundle
  Expected in: /usr/lib/libpq.5.dylib

dyld: Symbol not found: _PQresultMemorySize
  Referenced from: /Users/ユーザー名/project/プロジェクト名/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg_ext.bundle
  Expected in: /usr/lib/libpq.5.dylib

zsh: abort      bin/rails db:create
```

このエラーの解決法は下記stackoverflowに載っていました。

https://stackoverflow.com/questions/59846019/rails-postgres-dyld-lazy-symbol-binding-failed-symbol-not-found-pqresultme

参考にしつつ、下記実施してみます。

```ruby:ターミナル
① pg_ctl -D '/usr/local/var/postgresql@13' -l logfile stop　# サーバー停止
```

```ruby:ターミナル
② brew install libpq # libpqのインストール
```

```ruby:ターミナル
③ echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> ~/.zshrc　# パスを通す
```

```ruby:ターミナル
④ pg_ctl -D '/usr/local/var/postgresql@13' -l logfile start　# サーバー起動
```

では、もう一度 bin/rails db:create を実行してみます。

```ruby:ターミナル
bin/rails db:create
```

```ruby:結果
Created database 'プロジェクト名_development'
Created database 'プロジェクト名_test'
```

今度こそデータベースが作成できました！