Prisma + MySQL でユニーク制約を削除する
概要
Prismaを使った開発中、DBのスキーマを変更する際、schema.prisma
を変更して、migrationファイルを自動生成させるかと思います。
ただし、ユニークキーを取り除きたい場合は、MySQLをDBとして使用していると、自動でmigrationファイルが生成されません。
この記事では、Prisma + MySQLで、手動でmigrationファイルを作成することで、ユニーク制約を削除する方法について解説します。
- 環境
- MySQL (8.0)
- Prisma (v4.14.0)
prisma migrate devでは、ユニーク制約を外せない
以下のモデルで、Profile.userId
のユニーク制約を外すことを考えます。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
posts Post[]
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
単純に、Profile.userId
の @unique
を削除して、prisma migrate dev
を実行してみると、スキーマの変更が検出されず、migrationファイルの生成もスキーマの変更も行われません。
schema.prisma
の変更
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
- userId Int @unique
+ userId Int
}
prisma migrate dev
の実行結果
% npx prisma migrate dev --name remove_unique_constraint_on_profile_user_id
~~~ (出力抜粋)
Already in sync, no schema change or pending migration was found.
調べてみると、prismaのバグ?のようで、migrationファイルを自動生成してのschema変更はできないようです。
migrationファイルを手動で生成してスキーマを変更する
自動生成でのschema変更はできないようなので、上記のIssue にある通り、手動でmigrationファイルを作成してスキーマを変更します。
まずは、migrate dev --create-only
を使って空のmigrationファイルを作成します。
% npx prisma migrate dev --name remove_unique_constraint_on_profile_user_id --create-only
~~~ (出力抜粋)
Prisma Migrate created the following migration without applying it 20231020092516_remove_unique_constraint_on_profile_user_id
You can now edit it and apply it by running yarn prisma migrate dev.
これで、migrations/
のフォルダに空のmigrationファイルが作成されます。
-- This is an empty migration.
続いて、こちらのSQLファイルに、ユニーク制約を削除するSQL文を書きます。
MySQLでは、外部キー制約のあるカラムのインデックスは削除できない仕様なので、一度外部キー制約を外してからユニーク制約を外し、外部キー制約を付け直します。
また、foreign key名やindex名は、MySQLでshow create table テーブル名
などで確認できます。
-- drop foreign key
ALTER TABLE `profiles`
DROP FOREIGN KEY `profiles_userId_fkey`;
-- remove unique constraint
ALTER TABLE `profiles`
DROP INDEX `profiles_userId_key`;
-- add foreign key
ALTER TABLE `profiles`
ADD CONSTRAINT `profiles_userId_fkey`
FOREIGN KEY (`userId`) REFERENCES `users`(`id`);
最後に、migration deploy
をすればschemaとmigrationの履歴が更新され、正しくユニーク制約が外れます。
% npx prisma migration deploy
Discussion