🙄

Laravelでローカル/開発環境のDynamoDBに対してマイグレーションを行う

2023/11/04に公開

チーム開発を行う際や異なる環境間でのDynamoDBのスキーマの整合性を担保するために、マイグレーションでスキーマ管理をしたいということがある。
しかしLaravelはDynamoDBへマイグレーションを行う仕組みを持っていないため、少し工夫する必要がある。

バージョン

  • PHP 7.2.10
  • Laravel 10.29.0
  • LocalStack 0.14.4

前提

  • LocalStack、baophamを使用してDynamoDBを使用できるようになっていること
    LaravelでDynamoDBを使用できるようにするまではこちらの記事を参照のこと。

やること

  1. SQLiteに対してマイグレーションが実行されるよう設定(migrationsテーブルがSQLiteに作成されるようにする。)
  2. マイグレーションファイルを作成してup/downメソッドをDynamoDBに対してテーブル操作を行うような内容にする。

Laravelは初回マーグレーション時にmigrationsテーブルを自動で作成するようになっており、以後マイグレーションの度にマイグレーションの実施状況をmigrationsテーブルに保持している。
このmigrationsテーブルをDynamoDBに作成するのは難しいのでmigrationsテーブルのみSQLiteで保持するようにする。

SQLiteとは?

SQLiteは、軽量でファイルベースのデータベースです。サーバー設定不要で、アプリケーションに直接組み込んで使用でき、多くのプラットフォームに対応しています。データベース全体を単一のファイルとして扱うため、設定が簡単で移植性が高いです。(by Chat GPT)

拡張子.sqliteで作成したファイルにデータを保存することができ、手軽に使うことができる。
セキュリティや同時書き込みができないことがデメリットとして挙げられるが、今回扱うのはmigrationsテーブルのみで機密データではなく、また同時書き込みも想定されないのでSQLiteを使用する。

手順

SQLiteを使用するよう設定

  1. databaseフォルダ直下にdatabase.local.sqliteファイルを作成
  2. .envを編集
.env
- DB_CONNECTION=mysql
- DB_HOST=127.0.0.1
- DB_PORT=3306
- DB_DATABASE=laravel
- DB_USERNAME=root
- DB_PASSWORD=

+ DB_CONNECTION=sqlite
+ DB_DATABASE=database/database.local.sqlite

マイグレーションファイルを作成/修正

マイグレーションを実行した際にDynamoDBに対してスキーマ操作を行うよう修正。

database/migrations/xxxx_create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use BaoPham\DynamoDb\DynamoDbClientService;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        $dynamoDbClientService = resolve(DynamoDbClientService::class);
        $client = $dynamoDbClientService->getClient();

        $params = [
            'TableName' => 'Users',
            'KeySchema' => [
                [
                    'AttributeName' => 'id',
                    'KeyType' => 'HASH',
                ],
            ],
            'AttributeDefinitions' => [
                [
                    'AttributeName' => 'id',
                    'AttributeType' => 'N'
                ],
            ],
            'ProvisionedThroughput' => [
                'ReadCapacityUnits' => 10,
                'WriteCapacityUnits' => 10,
            ],
        ];

        $client->createTable($params);
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        $dynamoDbClientService = resolve(DynamoDbClientService::class);
        $client = $dynamoDbClientService->getClient();

        $params = [
            'TableName' => 'Users',
        ];

        $client->deleteTable($params);
    }
};

マイグレーション実行

これであとはいつも通りマイグレーションのコマンド実行する。

$ php artisan migrate

↓Usersテーブルが追加された。

※(おまけ)マイグレーション実行対象の環境を変えたい場合

dev環境で使用したい場合

  1. databaseフォルダ直下にdatabase.dev.sqliteファイルを作成
  2. .envを編集
.env
DB_CONNECTION=sqlite
DB_DATABASE=database/database.dev.sqlite

DYNAMODB_CONNECTION=aws
DYNAMODB_KEY=[AWSのアクセスキー]
DYNAMODB_SECRET=[AWSのシークレットキー]
DYNAMODB_REGION=ap-northeast-1

参考

https://igliop.medium.com/building-a-serverless-application-with-laravel-react-and-aws-lambda-d1f978a69fde
https://tech.willgate.co.jp/entry/2018/02/28/134537#マイグレーションは-RDBMS-と区別しない

Discussion