BlitzJSのDBをMySQLに変えてみた

技術ネタ
この記事は約12分で読めます。

こんばんわ、hisayukiです❗

今回は前回DBの設定をSQLiteからMySQLに対してやれるようにしようと思います。
PostgreSQLは公式でやり方が乗っているのでそちらを参照してください❗

スポンサーリンク

DockerComposeに追加

いつもの作業用コンテナはDocker-Composeで立ち上げているので、作業用コンテナと一緒にMySQLを立ち上げました。

mori-hisayuki/react-container
Contribute to mori-hisayuki/react-container development by creating an account on GitHub.

version: '3.2'
services:
  # MySQL
  local-mysql:
    image: mysql:8.0.23
    container_name: local-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: DEVELOP_DATABASE
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    volumes:
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
      # dockerコンテナとして起動したときに、ここにあるSQL文を実行
      - ./mysql/init:/docker-entrypoint-initdb.d
      # 永続化するときにマウントするdir
      - db-store:/var/lib/mysql
      # logの出力先
      - ./mysql/logs:/var/log/mysql
    ports:
      - 3306:3306
  node:
    container_name: local-node
    # ホスト名を明示的に指定する
    hostname: local-node
    build:
      context: .
      dockerfile: ./amd/Dockerfile
      args:
        USER_ID: 1000
        USER_NAME: vscode
        GROUP_ID: 1000
        GROUP_NAME: vscode
    env_file: devcontainer.env
    environment:
      - TZ=JST-9
    ports:
      - 80:80
      - 8080:8080
      - 3000:3000
      - 5500:5500
    volumes:
      - ~/.aws:/home/vscode/.aws
      - ~/.ssh:/home/vscode/.ssh
    command: /bin/sh -c "while sleep 1000; do :; done"
volumes:
  db-store:

設定変更

.env.local .env.test.local

どちらもコンテナで立ち上げたMySQLを向くようにします。
rootユーザーじゃないと出来なかったので、rootユーザーとrootのパスワード指定します。
あとはHOSTにはcontainer_nameで指定した名前、データベース名を指定します。

DATABASE_URL=mysql://root:root@local-mysql:3306/DEVELOP_DATABASE

schema.prisma

DBの種類をsqliteからmysqlに変更します

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

Migrationsを作り直し

あとからやると、マイグレーション周りが結構面倒です。
今回は前回行ったQuestionやChoiceの追加も含めて、initial_migrationにまとめちゃいます。

まずはmigrationsディレクトリをディレクトリごと削除します。
削除後に、マイグレーションコマンドを実行します。

blitz prisma migrate dev 
Environment variables loaded from .env
(node:2392) [DEP0111] DeprecationWarning: Access to process.binding('http_parser') is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
Prisma schema loaded from db/schema.prisma
Datasource "db": MySQL database "DEVELOP_DATABASE" at "local-mysql:3306"

? - Drift detected: Your database schema is not in sync with your migration history.
- The following migration(s) are applied to the database but missing from the local migrations directory: 20210504171618_


We need to reset the MySQL database "DEVELOP_DATABASE" at "local-mysql:3306".
Do you want to continue? All data will be lost. › (y/N)

すべてのデータが削除されるかを聞かれますが、そのまま続けます。
テーブルをすべて作り直すので、データは実際に消えてしまいます。

? Name of migration › 

マイグレーションに名前をつけるように言われるので、今回はinitial_migrationと付けます。

✔ Name of migration … initial_migration
The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20210504172200_initial_migration/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (2.20.1) to ./node_modules/@prisma/client in 129ms

完了するとマイグレーション用のSQLがMySQL用のSQLに変更されています。

-- CreateTable
CREATE TABLE `User` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `name` VARCHAR(191),
    `email` VARCHAR(191) NOT NULL,
    `hashedPassword` VARCHAR(191),
    `role` VARCHAR(191) NOT NULL DEFAULT 'USER',
UNIQUE INDEX `User.email_unique`(`email`),

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Session` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `expiresAt` DATETIME(3),
    `handle` VARCHAR(191) NOT NULL,
    `hashedSessionToken` VARCHAR(191),
    `antiCSRFToken` VARCHAR(191),
    `publicData` VARCHAR(191),
    `privateData` VARCHAR(191),
    `userId` INTEGER,
UNIQUE INDEX `Session.handle_unique`(`handle`),

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Token` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `hashedToken` VARCHAR(191) NOT NULL,
    `type` VARCHAR(191) NOT NULL,
    `expiresAt` DATETIME(3) NOT NULL,
    `sentTo` VARCHAR(191) NOT NULL,
    `userId` INTEGER NOT NULL,
UNIQUE INDEX `Token.hashedToken_type_unique`(`hashedToken`, `type`),

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Question` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `text` VARCHAR(191) NOT NULL,

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Choice` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `text` VARCHAR(191) NOT NULL,
    `votes` INTEGER NOT NULL DEFAULT 0,
    `questionId` INTEGER NOT NULL,

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- AddForeignKey
ALTER TABLE `Session` ADD FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Token` ADD FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Choice` ADD FOREIGN KEY (`questionId`) REFERENCES `Question`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

ここまでで設定変更は完了です。
既にマイグレーションも終わっているので、MySQLへのテーブル作成も完了しています。

確認方法

次は正常にMySQLに切り替わっているかの確認をします。
まずは、SQLiteではないことの確認は.sqliteファイルが出来ていなことで確認できます。

マイグレーション後に.sqliteファイルがなければSQLiteではなくなっています。

その状態でPrisma StudioでDBの中身を確認します。

blitz prisma studio

.envファイルで接続先はMySQLに対しての接続方法にしているので、この画面が出ればMySQLに保存されていることがわかります。

まとめ

今回DBを外だしにしました。
公式としても、SQLiteから別のDBへの切り替えを推奨しています。

Note that when starting your first real project, you may want to use a more scalable database like PostgreSQL, to avoid the pains of switching your database down the road. For more information, see Database overview. For now, we will continue with the default SQLite database.


ここにも書かれていますが、一番最初にやったほうがいいなーって思いましたね・・・
せっかくマイグレーション履歴を残していたのが、結局は一つにまとめられてしまうので😅

ただ、PrismaのおかげでSQLの書き換えの必要もないですし切り替えそのものはすごい簡単でした❗
今はコンテナで作ったMySQLですが、AWSのRDSやFaunaDBに対してのGraphQLもやっていきたいなーって思います❗

次回はチュートリアルの続きをやりますが、このままMySQLでやっていこうと思います❗

コメント