Help us understand the problem. What is going on with this article?

【Laravel】『Database does not exist.』エラーの原因と対処法

スクリーンショット 2020-01-18 10.30.34.png

PHPフレームワークLaravel入門を学習中にデータベースにアクセスできない問題が発生しました。

エラーメッセージは『Database does not exist.(SQL:PRAGMA foreign_keys = ON;)』との表示。

.envファイルのDB_DATABASE=database.sqliteをコメントアウトすることで解決したのですが、この記事では詳しい原因と対処法をお伝えします。

エラーメッセージの意味

『Database does not exist.(SQL:PRAGMA foreign_keys = ON;)』

こちらのメッセージ、意味は「データベースが存在しません。」です。
本では誤植があったようで、実際にはデータベースファイル(database.sqlite)のパスを指定する必要がありましたが、DB_DATABASE=database.sqLiteと入力していたため、「データベースが存在しない」というエラーが発生したようです。

さらなる問題と対処法

誤植に気付き、ファイルパスを絶対パスで記入したところ、The environment file is invalid!のエラー。
詳細はFailed to parse dotenv file due to unexpected whitespace.(予期しない空白のため、dotenvファイルの解析に失敗しました。)とのこと。
おそらくファイルパスに日本語が含まれていたため、うまくいかなかったのでしょう。

相対パスでの表記もうまくいかず、対処法を探したところ.envファイルのDB_DATABASE=〜をコメントアウトすることでうまくいくとのこと。

.envビフォー
# 前略
DB_DATABASE=# 後略
.envアフター
# 前略
# DB_DATABASE=〜
# 後略

【参考】laravelにてdatabase.sqliteが存在しない(does not exist)と表示される|teratail

実際に書き換えて、サーバーを立ち上げ直したところ、きちんと動作しました。

対処法解説

では、なぜDB_DATABASE=〜をコメントアウトすることで、きちんと動作するようになったのでしょうか?

Laravelではデータベースを指定する際にconfig/database.phpから設定を読み込みます。
このdatabase.phpではデータベースの指定に以下のようなコードが書かれています。

database.php
# 前略
'database' => env('DB_DATABASE', database_path('database.sqlite')),
# 後略

まず、env()から見ていきましょう。

グローバルヘルパー関数 env()

ここで使われているenv()はLaravelに用意されているグローバルヘルパー関数の1つで、環境変数の値を取得します。
取得できない場合はデフォルト値を返します。

$env = env('APP_ENV');

// APP_ENVがセットされていない場合、第二引数がデフォルト値('production')として返る
$env = env('APP_ENV', 'production');

database.phpに書かれているenv('DB_DATABASE', database_path('database.sqlite'))は、「環境変数DB_DATABASEに保存されている値を取得する!なければdatabase_path('database.sqlite')の値を使う!」ということだったんですね。

【参考】ヘルパ 5.5 Laravel( env() )

では、DB_DATABASEをコメントアウトすることで、取得するようになる第二引数database_path('database.sqlite')はどういう関数なのでしょうか?

グローバルヘルパー関数 database_path()

database_path()もグローバルヘルパー関数のひとつです。
database/ディレクトリの完全パスを返します。
database/ディレクトリ内の指定ファイルへの完全パスを生成することもできます。

$path = database_path();

// databaseディレクトリ内のfactories/UserFactory.phpへの完全パスを生成
$path = database_path('factories/UserFactory.php');

env('DB_DATABASE', database_path('database.sqlite'))で使われていたdatabase_path('database.sqlite')は「database/ディレクトリのdatabase.sqliteの完全パスを取得する!」ということだったんですね。

【参考】ヘルパ 5.5 Laravel( database_path() )

2つの関数をまとめると

それぞれの関数でやっていることがわかったので、database.phpに書かれている

database.php
# 前略
'database' => env('DB_DATABASE', database_path('database.sqlite')),
# 後略

が何をしているかをまとめると、

環境変数DB_DATABASEに保存されている値を取得する!なければdatabase/ディレクトリのdatabase.sqliteの完全パスを取得する!

ということになります。

対処法として行った「.envファイルのDB_DATABASE=database.sqliteをコメントアウトする」というのは、database_path()で取得した完全パスをデータベースとして指定するようにするということだったんですね!

その他の対処法

そうなると、「.envファイルのDB_DATABASE=database.sqliteをコメントアウトする」以外にも対処法が見えてきますね!

.envファイルのDB_DATABASE=database.sqliteをコメントアウトせずに

database.php
# 前略
'database' => env('DB_DATABASE', database_path('database.sqlite')),
# 後略

database.php
# 前略
'database' => database_path('database.sqlite'),
# 後略

のように変更して、環境変数の読み込みをなくして直接database.sqliteの完全パスを指定してもきちんと動作するようになりました。

まとめ

Laravelで『Database does not exist.』のエラーが出た際は、データベースのパスの指定が間違っている可能性があるので、

  • .envファイルのDB_DATABASE=database.sqliteをコメントアウト
.env
# 前略
# DB_DATABASE=〜
# 後略

もしくは

  • 環境変数の読み込みをなくして直接database.sqliteの完全パスを指定
database.php
# 前略
'database' => database_path('database.sqlite'),
# 後略

を試してみましょう!

参考まとめ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした