LaravelでSQLiteデータベースを使ってみよう
本文書の内容はLaravel11.x、Laravel10.x、Laravel9.x、Laravel8.x、Laravel6.x、laravel5.8とlaravel5.7で動作確認を行っています。Laravelに新しいバージョンがリリースされる度に記事の更新を行っているので本記事ではLaravel11の情報を含んだ内容に更新されています。Laravel11へのバージョン時に大きな変更がありましたがSQLiteの基本的な利用方法は全く変わりません。
Laravelを使ってアプリケーションを構築する際には必ずデータベースが必要になりますが、今回はシンプルで簡単に利用できるSQLiteデータベースを使ってテーブルの作成と操作方法の確認を行います。SQLiteは本記事だけではなくLaravelの動作確認等に頻繁に利用されているので開発時にLaravelでデータベースを操作したい場合にお勧めのデータベースです。Laravelに限らずさまざまな開発環境で利用されています。本文書では一部ですがSQLite上で実行することができるコマンドラインも紹介しているのでLaravelとの連携だけではなく単独のSQLiteについての知識も深めることができます。コマンドラインを利用した方法がわかっていれば何か問題が発生した場合でも直接アクセスして情報を取得することができます。
SQLiteデータベースはMySQLと同じリレーショナルデータベースなのでSQLiteでの開発した内容をそのままMySQLデータベースで利用することができます。
macOS環境で動作確認を行っておりデフォルトでSQLiteがインストールされているためすぐに使用することができます。Windowsでもhttps://www.sqlite.org/index.htmlからダウンロードして利用することができます。
Laravelプロジェクトが作成されていることを前提になっているのでプロジェクトを作成していない場合は最初にLaravelプロジェクトの作成を行ってください。
目次
Laravel11とデータベース
Laravel11ではプロジェクトを作成する際にデータベースを選択することができSQLiteデータベースを選択するとこれまで手動で行ってきたデータベースファイルの作成, .envファイルの設定, マイグレーションを自動で行ってくれます。
下記のようにプロジェクトの作成の途中でどのデータベースを利用するか聞かれるのでSQLiteデータベースを選択してください。
┌ Which database will your application use? ───────────────────┐
│ ○ MySQL │
│ ○ MariaDB │
│ ○ PostgreSQL │
│ › ● SQLite │
│ ○ SQL Server │
└──────────────────────────────────────────────────────────────┘
プロジェクト作成後の.envファイルではDB_CONNECTIONにsqliteの設定が行われています。
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
SQLiteのデータベースファイルはdatabaseディレクトリの下にdatabase.sqliteという名前で作成されています。
SQLiteデータベースの設定
これまで通り手動でSQLiteデータベースの設定を行いたい場合は下記の手順で行ってください。
SQLiteデータベースの作成
touchコマンドを使用してLaravelインストールディレクトリの下にあるdatabaseディレクトリの中にdatabase.sqliteを作成します。
SQLiteデータベースはファイルベースのデータベースなのでデータの保存先にファイルを利用します。SQLiteに限らずtouchコマンドは中身が空のファイルを作成する場合に利用させるコマンドです。VSCodeなどエディターを利用している場合はtouchコマンドを利用する必要はなくただ新規のファイルを作成することで同様の処理を行うことができます。
$ touch database/database.sqlite
datababase.sqliteという名前をつけたのには意味がありconfigディレクトリの中のデータベースの設定ファイルdatabase.phpファイルのsqliteの設定箇所にdatabase.sqliteが指定されているためです。
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
.envファイルの編集
Laravelの初期設定ではデータベースはmysqlへの接続が前提になっているのでLaravelインストールディレクトリにある環境変数設定ファイル”.env”を編集します。
【編集前】
//Laravel10の場合
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel10
DB_USERNAME=root
DB_PASSWORD=
//Laravelのバージョンが古い場合
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
【編集後】
DB_CONNECTIONの値をmysqlからsqliteに更新して、DB_HOSTからDB_PASSWORDまでの行はすべて削除します。先頭にDB_とつき変数はDB_CONNECTIONのみになります。
DB_CONNECTION=sqlite
ここまでの設定でLaravelからSQLiteを利用することができます。
php artisan migrateでテーブルの作成
SQLiteデータベースの作成、SQLiteに関するLaravelの設定が完了したので、テーブルの作成を行います。Laravelインストール直後でもphp arisan migrateコマンドを使用するとusersテーブルとpassword_resetsテーブルがデータベースに作成されます。下記はLaravel10で実行した時に作成されるテーブルです。Laravelのバージョンによって作成されるテーブルが異なります。
//Laravel10の場合
% php artisan migrate
INFO Preparing database.
Creating migration table .................................. 5ms DONE
INFO Running migrations.
2014_10_12_000000_create_users_table ................... 4ms DONE
2014_10_12_100000_create_password_reset_tokens_table.... 1ms DONE
2019_08_19_000000_create_failed_jobs_table ............. 3ms DONE
2019_12_14_000001_create_personal_access_tokens_table .. 3ms DONE
//古いLaravelの場合
laravel $ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (3.67ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (1.71ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (1.85ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (2.52ms)
php artisan migrate実行後、上記のようにMigration table create successfully(成功)が表示されればsqliteに4つのテーブルが作成されています。
Laravel10ではdatabase.sqliteを作成し忘れていたとしてもdatabaseフォルダにdatabase.sqliteファイルを作成するかどうか確認してくれます。
% php artisan migrate
WARN The SQLite database does not exist: database/database.sqlite.
Would you like to create it? (yes/no) [no]
テーブル作成までの手順等に誤りがある場合は、php artisanを実行すると下記のエラーが発生するのでエラーを確認して対応を行ってください。(Laravelの古いバージョンを利用した場合)
laravel $ php artisan migrate
Illuminate\Database\QueryException : Database (homestead) does not exist. (SQL: PRAGMA foreign_keys = ON;)
SQLiteを利用した場合にテーブル作成のエラーの原因は主に以下の可能性が高いです。
- databaseディレクトリの下にdatabase.sqliteが作成されていない
- database.sqliteファイルの名前が間違っている
- .envファイルの設定がデフォルトのmysqlの設定のままになっている
SQLiteのコマンドによるデータベースの確認
データベースに保存されているデータを確認した場合はGUIの管理ツールを利用することができます。最近ではTablePlusのGUI管理ツールを利用している人も多いです。
GUI管理ツールを使うことも可能ですが、SQLiteを理解するためにSQLiteのコマンドを使用して本当にテーブルが作成できているのかを確認してみましょう。作成したdatabase.sqliteのあるdatabaseディレクトリに移動して、sqlite3コマンドでファイルを指定します。接続するとsqliteのバージョンを確認することができます。
% sqlite3 database.sqlite
SQLite version 3.43.2 2023-10-10 13:08:14
Enter ".help" for usage hints.
sqlite>
.tablesコマンドを実行するとデータベース内に作成されたテーブルを確認することができます。5つのテーブルが作成されています。migrationsテーブルはテーブルを作成/更新/変更する際に利用するmigrationファイルの実行履歴を管理するテーブルです。
sqlite> .tables
#Laravel11の場合
cache job_batches password_reset_tokens
cache_locks jobs sessions
failed_jobs migrations users
#Laravelの以前のバージョン
failed_jobs password_resets users
migrations personal_access_tokens
users, password_resets, failed_jobs, personal_access_tokensはテーブルが作成されているだけで中身が空です。migrationsテーブルにはusersとpassword_resets, failed_jobs, personal_access_tokensの履歴が残されているはずなので、確認してみましょう。そのまま実行しても列名が表示されないので、”.headers on”でヘッダーを表示させます。実行するとusers, password_resets, failed_jobs, personal_access_tokensのmigrationの情報を確認することができます。.header onを実行していることでテーブルの列名が表示されます。
sqlite> .headers on
sqlite> select * from migrations;
#Laravel11の場合
id|migration|batch
1|0001_01_01_000000_create_users_table|1
2|0001_01_01_000001_create_cache_table|1
3|0001_01_01_000002_create_jobs_table|1
#Laravelの以前のバージョン
id|migration|batch
1|2014_10_12_000000_create_users_table|1
2|2014_10_12_100000_create_password_resets_table|1
3|2019_08_19_000000_create_failed_jobs_table|1
4|2019_12_14_000001_create_personal_access_tokens_table|1
SQLiteのコマンドを終了する際は、.quitで終了することができます。SQLiteはMySQLのように起動したり停止したりする必要はありません。
テーブルへデータを追加してみよう
sqliteでのデータベース、テーブルの作成方法を確認しました。LaravelにはSeederという機能で一括でダミーデータを登録することができますが、今回はtinkerを使って手動で行ってみましょう。
tinkerはLaravelアプリケーションにコマンドラインでアクセスすることできるツールでtinker上でテーブルへのデータ追加を行うことができます。
tinkerを使ってユーザ登録
tinkerの実行はLaravelのプロジェクトディレクトリ直下で行う必要があります。phpコマンドで指定しているartisanファイルがLaravelのプロジェクトディレクトリに存在するためです。
% php artisan tinker
Psy Shell v0.11.17 (PHP 8.1.6 — cli) by Justin Hileman
別のディレクトリでtinkerを実行すると以下のエラーが表示されます。artisanファイルが存在しないためです。
% php artisan tinker
Could not open input file: artisan
下記の手順でユーザを作成することができます。passwordの部分だけbcrypt関数を使用しているのはpasswordの文字列を暗号化するためです。Laravel7まではモデルファイルはApp¥UserでしたがLaravel8以降はApp¥Models¥Userに代わっています。下記はLaravel10のtinkerで実行しています。
>>> $user = new User();
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= App\Models\User {#4430}
> $user->name = 'John';
= "John"
> $user->email='johndoe@example.com';
= "johndoe@example.com"
> $user->password = bcrypt('password')
= "$2y$10$wAtFiqYSuVQJn6yzI5HeQ.5mtR5vTm29sL6Oi9yokdMBT7cSm7DIm"
> $user->save();
= true
>>> quit
ユーザの作成が完了したら、sqlite3コマンドを使ってデータベースに接続してをusersテーブルに登録が完了しているのか確認してみましょう。
vue $ sqlite3 database/database.sqlite
SQLite version 3.13.0 2016-05-18 10:57:30
Enter ".help" for usage hints.
sqlite> .headers on
sqlite> select * from users;
id|name|email|email_verified_at|password|remember_token|created_at|updated_at
1|John|johndoe@example.com||$2y$10$JWI2sxGQ3TTAFiIZi5o0nuCFqwmr/.yJy/SwDTLZivFTmXyg6i5I.||2023-05-08 01:33:49|2023-05-08 01:33:49
tinkerを使用することでユーザが作成できることが確認できました。tinkerでもテーブルに登録されているユーザ一覧を取得することができます。
$ php artisan tinker
Psy Shell v0.11.2 (PHP 8.0.7 — cli) by Justin Hileman
> $users = User::all();
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= Illuminate\Database\Eloquent\Collection {#4442
all: [
App\Models\User {#4444
id: "1",
name: "John",
email: "johndoe@example.com",
email_verified_at: null,
#password: "$2y$10$ayHgAAMzTyZApnl9vqOEEOknS83Kn.5Vo4wHDgn0t.8IIxauLSiXG",
#remember_token: null,
created_at: "2022-03-12 00:31:49",
updated_at: "2022-03-12 00:31:49",
},
],
}
sqlite3を使ってSQLiteデータベースに接続してテーブルの中身を確認することができました。tinkerでは上記のようにApp¥Models¥Userモデル(古いバーションはApp¥User)を経由してデータベースへ接続を行うため、MySQLでもSQLiteでも他のデータベースで作成していても同じ方法でデータベースへの接続を行うことができます。Laravelもtinkerと同様にモデルを経由してアクセスするため直接データベースにアクセスすることがない限りどのデータベースで作成されているか意識することはありません。
テーブルにアクセスした場合に[PDOException] SQLSTATE[HY000] [2002] Connection refusedエラーが発生した場合は、php arisan serveを一度停止し、再度実行してみてください。
SQLiteのコマンド
作成されたテーブルの確認(スキーマ情報)
.shemaコマンドを実行するとテーブルが作成された際に実行されたsqlを確認することができます。
sqlite> .schema
CREATE TABLE "migrations" ("id" integer not null primary key autoincrement, "migration" varchar not null, "batch" integer not null);
//略
select文による表示
sqlite3でSQLiteデータベースにアクセス後にselect文を実行するとヘッダーは表示されません。
sqlite> select id, name, email from users;
1|John Doe|johndoe@example.com
.header onをつけてselect文を実行するとヘッダーが表示されます。
sqlite> .header on
sqlite> select id, name, email from users;
id|name|email
1|John|johndoe@example.com
ヘッダーが表示しても列間にスペースがないため読みずらいため.mode columnを実行します。最初のselect文よりもすっきり表示させることができます。
sqlite> .mode column
sqlite> select id, name, email from users;
id name email
---------- ---------- -------------------
1 John Doe johndoe@example.com
sqlite3コマンドの一部を説明しましたがLaravelでアプリケーションを構築する際にsqlite3コマンドを利用することはありません。しかし何か問題が発生してGUIの管理ソフトウェアが利用できない場合にtinkerだけでなくsqlite3コマンドが利用できるということを知っておくだけで対応することができるはずです。直接コマンドを実行して動作確認することでデータベースはどのように操作することができるか理解できることはバックエンドの技術を理解する上で重要です。