DSQL用のPrismaツールを使ってみる
はじめに
少し前に、DSQL用のPrisma CLIツールがAWS公式から発表されました。
Aurora DSQL launches new support for Tortoise, Flyway, and Prisma - AWS
この記事では、このツールを実際に使って、どのようなことができるのか試してみたいと思います。
Prisma CLIツール
リポジトリは以下です。
aurora-dsql-orms/node/prisma at main · awslabs/aurora-dsql-orms
README.mdを読むと、大きく以下の機能をサポートしているようです。
- Schema Validator(
validateコマンド):PrismaスキーマがDSQL互換かどうかチェック - Migration Linter(
lintコマンド):マイグレーションSQLがDSQL互換かどうかチェック - Migration Transformer(
transformコマンド):マイグレーションSQLをDSQL互換のSQLに変換 - All-in-one Migrate Command(
migrateコマンド):検証、生成、変換をワンステップで実行
前提
- Node.jsのバージョンが20以上であること
- この記事では
v25.2.1を使用
- この記事では
- Prismaがインストール済みであること
- この記事では
7.8.0を使用
- この記事では
また、この記事では、既にPrismaで何回かマイグレーションを実施済みの、以下のスキーマが入ったプロジェクトで確認します。
DSQLでは、ASYNCキーワードを付けない同期的なインデックスやSERIAL型、外部キーがサポートされていません。今回使用するスキーマにはこれらがすべて含まれています。
スキーマファイル(prisma/schema.prisma)
generator client {
provider = "prisma-client-js"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model users {
id Int @id @default(autoincrement())
first_name String @db.VarChar(100)
email String @unique @db.VarChar(255)
created_at DateTime? @default(now()) @db.Timestamp(6)
age Int?
posts posts[]
}
model posts {
id Int @id @default(autoincrement())
author users @relation(fields: [authorId], references: [id])
authorId Int
created_at DateTime? @default(now()) @db.Timestamp(6)
@@index([created_at])
}
マイグレーションファイル①(prisma/migrations/20250822055143_add_users_table/migration.sql)
-- CreateTable
CREATE TABLE "public"."users" (
"id" SERIAL NOT NULL,
"name" VARCHAR(100) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "public"."users"("email");
マイグレーションファイル②(prisma/migrations/20250822055158_add_age/migration.sql)
-- AlterTable
ALTER TABLE "public"."users" ADD COLUMN "age" INTEGER;
マイグレーションファイル③(prisma/migrations/20250822055224_update_name_to_first_name/migration.sql)
/*
Warnings:
- You are about to drop the column `name` on the `users` table. All the data in the column will be lost.
- Added the required column `first_name` to the `users` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "public"."users" DROP COLUMN "name",
ADD COLUMN "first_name" VARCHAR(100) NOT NULL;
マイグレーションファイル④(prisma/migrations/20260626015411_add_posts_table/migration.sql)
-- CreateTable
CREATE TABLE "posts" (
"id" SERIAL NOT NULL,
"authorId" INTEGER NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "posts_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "posts_created_at_idx" ON "posts"("created_at");
-- AddForeignKey
ALTER TABLE "posts" ADD CONSTRAINT "posts_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
インストール
プロジェクトにaurora-dsql-prisma-toolsをインストールします。GitHubリポジトリに記載の以下のコマンドを実行します。
npm install --save-dev @aws/aurora-dsql-prisma-tools
スキーマの検証
スキーマ(schema.prisma)のDSQL互換性を検証するには以下のコマンドを実行します。スキーマを編集した直後やマイグレーションを生成する前に実行し、DSQL非対応の記述がないかを確認するために使います。
npx aurora-dsql-prisma validate prisma/schema.prisma
コンソールに以下のように表示されました。
Validating schema.prisma...
✗ Missing relationMode = "prisma" in datasource block (line 6)
→ Add relationMode = "prisma" to your datasource block. DSQL does not support foreign key constraints.
✗ Column `"id"` uses SERIAL, which is not supported in DSQL. (line 6)
→ Use `BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1)` instead.
✗ Column `"id"` uses SERIAL, which is not supported in DSQL. (line 17)
→ Use `BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1)` instead.
✗ CREATE INDEX without ASYNC is not supported in DSQL. Index: "users_email_key" (line 25)
→ Use `CREATE INDEX ASYNC ...` instead.
✗ CREATE INDEX without ASYNC is not supported in DSQL. Index: "posts_created_at_idx" (line 28)
→ Use `CREATE INDEX ASYNC ...` instead.
✗ ALTER TABLE ADD CONSTRAINT with FOREIGN KEY is not supported in DSQL. (line 31)
→ Remove the FOREIGN KEY constraint. Enforce referential integrity in application code.
✗ Validation failed: 6 error(s)
2つ目以降は、SERIAL型、同期インデックス、外部キーがDSQLでは対応していないということを示しています。
1つ目の警告は、PrismaのrelationModeをprismaにする必要があるという内容です。
relationModeは、レコード間の関係をどのように適用するかを指定するための設定です。foreignKeysとprismaのいずれかを指定します。foreignKeysを指定すると、データベースの外部キー制約を使用してリレーションが強制されます。prismaを指定すると、データベースの制約ではなく、Prismaによって処理されます。何も指定しない場合、デフォルトでforeignKeysになります。
DSQLは外部キーをサポートしていないため、foreignKeysは使えず、prismaを指定する必要があるということを示しています。
Manage relations between records with relation modes in Prisma | Prisma Documentation
以下のようにrelationModeをprismaに指定してから再度実行します。
datasource db {
provider = "postgresql"
relationMode = "prisma"
}
Validating schema.prisma...
✗ Column `"id"` uses SERIAL, which is not supported in DSQL. (line 6)
→ Use `BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1)` instead.
✗ Column `"id"` uses SERIAL, which is not supported in DSQL. (line 17)
→ Use `BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1)` instead.
✗ CREATE INDEX without ASYNC is not supported in DSQL. Index: "users_email_key" (line 25)
→ Use `CREATE INDEX ASYNC ...` instead.
✗ CREATE INDEX without ASYNC is not supported in DSQL. Index: "posts_created_at_idx" (line 28)
→ Use `CREATE INDEX ASYNC ...` instead.
✗ Validation failed: 4 error(s)
外部キーは定義したままですが、データベースの外部キー制約を使用するわけではないため、警告メッセージは出なくなりました。代わりに、schema.prismaに以下の警告メッセージが表示されるようになります。

外部キー制約を設定するとインデックスが自動で作成されますが、relationModeがprismaの場合はインデックスが作成されないため、パフォーマンスの低下を招く可能性があります。そのため、必要であれば手動でインデックスを追加するようにという警告です。
Manage relations between records with relation modes in Prisma | Prisma Documentation
マイグレーションSQLの検証
マイグレーションSQLのDSQL互換性を検証するには以下のコマンドを使用します。スキーマの検証と異なり、こちらは生成済みのマイグレーションファイルそのものを対象にします。
npx aurora-dsql-prisma lint migration.sql
引数にファイル名を1つ指定して、そのファイルをチェックする形式のコマンドです。
今回は複数のマイグレーションファイルを横断してチェックしたかったため、以下のコマンドをpackage.jsonに追加しました。
"scripts": {
"lint:migrations": "find prisma/migrations -name 'migration.sql' | xargs -I {} npx aurora-dsql-prisma lint {}"
}
以下の結果が出力されました。(ファイル名が<stdin>になってしまっていますが、一旦検証のためそのままにしています)
> prisma-playground@1.0.0 lint:migrations
> find prisma/migrations -name 'migration.sql' | xargs -I {} npx aurora-dsql-prisma lint {}
<stdin>:3: WARNING — Column `"id"` uses SERIAL, which is not supported in DSQL.
Replaced SERIAL with BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1) on column `"id"` — verify application code handles the wider type range
<stdin>:12: FIXED — CREATE INDEX without ASYNC is not supported in DSQL. Index: "users_email_key"
Added ASYNC keyword to CREATE INDEX
<stdin>:10: ERROR — ADD COLUMN 'first_name' with inline DEFAULT or NOT NULL constraint is not supported in DSQL.
→ Split into steps: CREATE TABLE with the column, or ADD COLUMN without constraints then backfill.
<stdin>:9: ERROR — ALTER TABLE DROP COLUMN ("name") is not supported in DSQL.
→ Recreate the table without the column, then migrate data.
<stdin>:3: WARNING — Column `"id"` uses SERIAL, which is not supported in DSQL.
Replaced SERIAL with BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1) on column `"id"` — verify application code handles the wider type range
<stdin>:11: FIXED — CREATE INDEX without ASYNC is not supported in DSQL. Index: "posts_created_at_idx"
Added ASYNC keyword to CREATE INDEX
<stdin>:14: WARNING — ALTER TABLE ADD CONSTRAINT with FOREIGN KEY is not supported in DSQL.
Removed ALTER TABLE ADD FOREIGN KEY constraint
マイグレーションファイルの中で、DSQLがサポートしていないSQL文を洗い出してくれています。内容は先ほどのスキーマ検証で検出されたものも含まれていますが、DROP COLUMNの非サポートなど、SQLレベルでのより細かいチェックを行っています。
マイグレーションSQLの変換
続いてマイグレーションSQLをDSQL互換のSQLに変換してみます。lintが問題の検出のみを行うのに対し、transformは検出した問題のうち構文の書き換えで対応できるものを実際に修正し、新しいSQLファイルとして出力します。
単一のSQLファイルを変換して新たなSQLファイルとして保存するコマンドは以下です。
npx aurora-dsql-prisma transform raw.sql -o migration.sql
raw.sqlをインプットとして読み込み、変換したものをmigration.sqlに保存します。
試しにマイグレーションファイル①を変換してみます。
npx aurora-dsql-prisma transform prisma/migrations/20250822055143_add_users_table/migration.sql -o test.sql
コンソールには以下の結果が表示され、DSQL互換になるようクエリの置き換えおよびキーワードが追加されたことがわかります。
<stdin>:3: WARNING — Column `"id"` uses SERIAL, which is not supported in DSQL.
Replaced SERIAL with BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1) on column `"id"` — verify application code handles the wider type range
<stdin>:12: FIXED — CREATE INDEX without ASYNC is not supported in DSQL. Index: "users_email_key"
Added ASYNC keyword to CREATE INDEX
出力されたSQLは以下の通りです。
CREATE TABLE "public"."users" (
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CACHE 1 ),
"name" VARCHAR(100) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX ASYNC "users_email_key" ON "public"."users"("email");
SERIAL型がBIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CACHE 1 )に変更され、インデックスにASYNCキーワードが追加されました。
続いてDROP COLUMNを含むマイグレーションファイル③を変換してみます。
npx aurora-dsql-prisma transform prisma/migrations/20250822055224_update_name_to_first_name/migration.sql -o test.sql
結果は以下のようになり、エラーで変換できませんでした。
<stdin>:10: ERROR — ADD COLUMN 'first_name' with inline DEFAULT or NOT NULL constraint is not supported in DSQL.
→ Split into steps: CREATE TABLE with the column, or ADD COLUMN without constraints then backfill.
<stdin>:9: ERROR — ALTER TABLE DROP COLUMN ("name") is not supported in DSQL.
→ Recreate the table without the column, then migrate data.
ADD COLUMNに対するNOT NULL指定はDSQLではサポートされていません。そのため、カラムの追加、値をバックフィルするUPDATE、そしてNOT NULL制約の追加を別トランザクションで行う必要があります。
また、DROP COLUMNをする場合は、そのカラムを除いたテーブルを作成し、後からデータを移行する必要があります。
クエリの置き換えやキーワードの追加で対応可能なものは変換できますが、これらのような複雑な手順が必要なものは変換できないようです。
検証、生成、変換を一気に実施
npx aurora-dsql-prisma migrate prisma/schema.prisma -o prisma/migrations/001_init/migration.sql
schema.prismaを初めからDSQL互換のマイグレーションファイルとして出力してくれます。
CREATE SCHEMA IF NOT EXISTS "public";
CREATE TABLE "users" (
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CACHE 1 ),
"first_name" VARCHAR(100) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
"age" INTEGER,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "posts" (
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CACHE 1 ),
"authorId" INTEGER NOT NULL,
"created_at" TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "posts_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX ASYNC "users_email_key" ON "users"("email");
CREATE INDEX ASYNC "posts_created_at_idx" ON "posts"("created_at");
新規にデータベースを構築する場合など、マイグレーション履歴を保持する必要がない場合はこちらのコマンドで一括生成するのが良さそうです。
補足
このツールを使えば機械的に変換可能な箇所は変換できますが、DSQLに移行するにあたり、本当に現在のスキーマで問題ないかは検討する必要があります。
例えば、SERIALを使っている場合、BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CACHE 1 )に変換されます。しかし、書き込み量の多いテーブルの場合、単調増加する整数よりランダムな主キーをAWSは推奨しています。そのため、テーブルの要件によっては主キーをUUIDに変更することを検討する必要があります。
Primary keys in Aurora DSQL - Amazon Aurora DSQL
おわりに
DSQL用のPrisma CLIツールを試してみました。スキーマ検証、SQL検証と変換、そして一括生成と、一通りの機能を確認できました。
DSQLは2024年12月に発表されて以来、複数の機能拡張が行われています。既存のプロジェクトをDSQLに移行したい、あるいはDSQLと平行稼働したいというケースもあるかと思います。そういった場合に役立つツールです。
ただし、自動的に変換できるのはあくまで機械的に書き換え可能な範囲までで、DROP COLUMNを伴う変更などは手動での対応が必要となります。移行の際は、このツールで洗い出した警告をもとに、最終的には手動での確認・修正が必要です。
この記事がどなたかの参考になれば幸いです。



