prisma-schema-fixer で schema.prisma を補正する
Prismaを使っていると、schema.prisma
ファイルで次のような命名規則を適用したいことがあります。
- テーブル名やカラム名をスネークケース(
user_profile
など)にしたい- DB設計の慣習としてスネークケースが一般的であるため
- データベース上のテーブル名は複数形(
users
)、コード上のモデル名は単数形(User
)にしたい
データベース上の名前は、@@map
や@map
で指定できますが、これを毎回書くのは大変です。
また、複数形/単数形のチェックはもっと大変です。
これを自動で行ってくれるツールとして、prisma-case-format
があります。
実際良く使われているツールで、筆者も使ってきました。
prisma-case-format
でも十分便利なのですが、さらに柔軟なカスタマイズができる新しいツールとしてprisma-schema-fixer
を作りましたので、今回はこちらを紹介したいと思います。
prisma-schema-fixer を作った経緯
prisma-case-format
を使っていて、prisma-case-format
に欲しい機能があってIssueをあげたり、依存ライブラリを更新するPull Requestを投げたりしてきたのですが、活動が1年くらい止まったままで動きがなさそうだったので、ならば自分でということで作りました。
最初はforkして作ろうと思ったのですが、今の形に機能として付け加えるのが厳しそうだったので、一から作り直した次第です。
prisma-schema-fixer で出来ること
prisma-schema-fixer
では、prisma-case-format
と同様に下記を補正することができます。
- データベース上のテーブル名/カラム名/列挙型の形式として、キャメルケース/パスカルケース/スネークケース
-
@@map
、@map
を自動で設定してくれます。
-
- TypeScript側のモデル名/フィールド名/enum名の形式として、キャメルケース/パスカルケース/スネークケース
- データベース上のテーブル名/列挙型、TypeScript側のモデル名/enum名の形式として、単数/複数形
- フィールドが配列の場合、複数形に
また、prisma-schema-fixer
だと出来ることとして下記があります。(prisma-case-format
だと出来ない)
- コードによる変換処理
- 関数を設定として定義できます。これにより、様々な変換処理が実装可能です。
- フィールドに対する属性の補完
- フィールドの型に応じて属性を補完してくれます。
prisma-schema-fixer
だと出来ることについては、以降で実際の例も交えて説明します。
(1) コードによる変換処理
prisma-schema-fixer
では、設定はJavaScriptとして記載します。
デフォルトだと、schema.prisma
同じフォルダにあるschema-fixer.config.mjs
というファイルを参照します。(コマンドの引数として設定ファイルのパスを指定することも可能)
この設定ファイルで変換処理を関数として書くことが可能です。たとえば、列挙型の名前として、enum_
という接頭辞を付与したい場合、下記のように書きます。
// @ts-check
/** @type {import("@onozaty/prisma-schema-fixer").Config} */
export default {
rules: {
"enum-map": [
{
case: "snake",
form: "plural",
func: (value) => `enum_${value}`,
},
],
},
};
func
が変換処理の関数となります。
この設定では、schema.prisma
で定義したenum名を元に、スネークケース、複数形にしたうえで、接頭辞としてenum_
を付けることになります。
以下は上記設定でのschema.prisma
の補正イメージです。
enum Role {
USER
ADMIN
+
+ @@map("enum_roles")
}
(2) フィールドに対する属性の補完
フィールドの型に応じて、属性を一括補完することができます。これにより、一貫性のある設定を保ちつつ、手作業による漏れを防ぐことができます。
Prismaでは、schema.prisma
で指定した型に応じて、データベース側のカラムの型が決まるようになっており、各データベース毎にデフォルトが決まっています。
たとえば、DateTimeは、PostgreSQLの場合はデフォルトではtimestamp without timezone
型になります。
これをtimestamp with timezone
型にしたい場合には、@db.Timestamptz()
を付与することで変更できます。
デフォルトから変えたい箇所が1箇所ならばよいのですが、それが全体となると、漏れが発生しかねません。
これをprisma-schema-fixer
では一括で属性を設定するように定義できます。
以下はDateTimeに対して全て@db.Timestamptz()
を付与する設定です。
// @ts-check
/** @type {import("@onozaty/prisma-schema-fixer").Config} */
export default {
rules: {
"field-attribute": [
{
typeToAttributes: {
"DateTime": ["@db.Timestamptz()"],
}
},
],
},
};
以下は上記設定でのschema.prisma
の補正イメージです。
model User {
id Int @id @default(autoincrement())
name String
- createdAt DateTime @default(now())
+ createdAt DateTime @default(now()) @db.Timestamptz()
- updatedAt DateTime @updatedAt
+ updatedAt DateTime @updatedAt @db.Timestamptz()
}
他にも、下記のような定型的なものに対して、漏れを防ぐのに役立ちます。
- フィールド名が
createdAt
で、型がDateTime
の場合、@default(now())
を付与 - フィールド名が
updatedAt
で、型がDateTime
の場合、@updatedAt
を付与
終わりに
使い方や設定の詳細については、READMEをご参照ください。
一通り欲しい機能は実装済みですが、他にもこういったルールが定義できるとうれしいなどありましたら、フィードバックいただけると助かります。
Discussion