接続の失敗
PostgreSQLインスタンスに接続しようとしている際に(デプロイ中やローカル開発環境のセットアップ中など)、接続が直ちに拒否され、次のメッセージが表示されることがあります。
FATAL: database "myapp_production" does not exist
このエラーは、パーミッションの問題やサーバー設定の問題のように聞こえるため厄介ですが、実際には、指定した正確な名前のデータベースが内部カタログに見つからないということをPostgreSQLが伝えているだけです。psql、Node.jsのnode-postgresクライアント、またはRailsのdatabase.ymlのいずれを使用している場合でも、根本的な原因はほとんどの場合、期待値と実際の状態の不一致です。
よくあるシナリオ
- データベースが作成されていない: PostgreSQLをインストールしたが、まだ
CREATE DATABASEコマンドを実行していない。 - 設定のタイポ:
.envファイルやアプリケーション設定におけるわずかなスペルミス。 - 大文字・小文字の区別: 大文字を含むデータベース名(例: "MyApp")を作成したが、"myapp"で検索している。
- デフォルトユーザーの挙動: 引数なしで
psqlを実行すると、システムユーザー名と一致するデータベース名がデフォルトで指定される。 - Dockerの初期化: コンテナは起動したが、初期化スクリプトが失敗したか、まだ実行されていない。
ステップ1:既存のデータベースを確認する
データベースが存在すると仮定する前に、サーバー上の実際のデータベース一覧を確認してください。デフォルトのpostgresデータベースに接続して、現在何が利用可能かを確認します。
psql -U postgres -d postgres -l
-lフラグはすべてのデータベースを一覧表示します。すでにpsqlセッション内にいる場合は、次のメタコマンドを使用します。
\l
出力を詳しく確認してください。リストに"myapp_production"がない場合、その特定のPostgreSQLインスタンスにデータベースが存在しないことが確認されたことになります。
ステップ2:不足しているデータベースを作成する
データベースがない場合は、作成する必要があります。これはコマンドラインまたはSQLプロンプトから行えます。
コマンドライン(シェル)を使用する場合
createdbユーティリティは、SQLコマンドのラッパーです。
createdb -U postgres myapp_production
SQLを使用する場合
postgresデータベースに接続して、以下を実行します。
CREATE DATABASE myapp_production;
大文字・小文字の区別に関する注意: CREATE DATABASE "MyApp";のように引用符を使用すると、PostgreSQLは大文字・小文字を保持します。後で-d myappを使用して接続しようとすると失敗します。簡素化のため、常に引用符なしの小文字の名前を使用することをお勧めします。
ステップ3:接続文字列と環境変数のデバッグ
リストにデータベースが存在しているにもかかわらず、アプリケーションでエラーが発生する場合は、接続文字列の構造を確認してください。一般的なURIは次のようになります。
postgresql://user:password@localhost:5432/myapp_production
.envファイルに末尾のスペースや隠し文字がないか確認してください。例えば、BashやDocker環境では、環境変数の末尾にあるスペースが文字列の一部として解釈されることがあります。
# 誤り
DB_NAME=myapp_production
# 正しい
DB_NAME=myapp_production
ステップ4:「デフォルトユーザー」の罠への対処
このエラーが発生する最も一般的なケースの1つは、psqlを単独で実行した場合です。デフォルトでは、PostgreSQLは現在のOSユーザー名と同じ名前のデータベースに接続しようとします。ユーザーがubuntuの場合、psqlの実行は次と同じ意味になります。
psql -d ubuntu
ubuntuという名前のデータベースを作成していない場合、FATAL: database "ubuntu" does not existというエラーが発生します。これを避けるために、常にデータベース名を明示的に指定してください。
psql -d postgres
ステップ5:Docker固有の修正
公式のPostgreSQL Dockerイメージを使用している場合は、POSTGRES_DB環境変数がアプリケーションが探しているものと一致していることを確認してください。コンテナがすでに初期化された後(つまり、/var/lib/postgresql/dataディレクトリが作成された後)にこの変数を変更しても、効果はありません。
Dockerでこれを修正するには、次のいずれかを行う必要があります。
- ボリュームを消去して再起動する(注意:これによりすべてのデータが削除されます):
docker-compose down -v - 実行中のコンテナに接続し、手動でデータベースを作成する:
docker exec -it my_postgres_container psql -U postgres -c "CREATE DATABASE myapp_production;"
検証
修正が適用されたと思ったら、直接接続テストを行って検証してください。アプリケーションがホストされているマシンから次のコマンドを実行します。
psql -h localhost -U your_user -d myapp_production -c "SELECT 1;"
1が1つ入ったテーブルが表示されれば、接続は成功です。依然としてFATALエラーが表示される場合は、正しいホストとポートに接続しているか再確認してください(例:リモートのRDSやDockerインスタンスではなく、ローカルのPostgresインスタンスに接続している可能性があります)。
学んだ教訓
PostgreSQLのデータベース名は厳密にチェックされます。将来このエラーを防ぐために、以下の点に注意してください。
- CI/CDパイプラインやセットアップスクリプトに、データベース作成ステップを含める。
- 大文字・小文字の区別による混乱を避けるため、データベース名には常に小文字を使用する。
psqlを頻繁に使用する場合は、シェルでPGDATABASE環境変数を明示的に定義する。- 動的な設定エラーを特定するために、実行時にアプリケーションが使用している特定の接続文字列をログで確認する。

