Prismaの最新リリースでは、改善されたデータモデル構文が導入されました。これにより、Prismaがこれまでデータベースレイアウトに関して行っていた多くの独断的な決定が削除され、開発者により多くの制御権が与えられます。

⚠️ この記事は古くなっています。これは現在非推奨となっているPrisma 1に関するものです。Prismaの最新バージョンについては、ドキュメントを参照してください。⚠️
この数ヶ月間、私たちはコミュニティと協力して、Prismaのための改善されたデータモデル仕様を定義してきました。この新しいバージョンはデータモデルv1.1と呼ばれ、本日の安定版リリースで利用可能です。ドキュメントはこちらでご確認ください。
本日より、Prismaの公開デモサーバーは新しいデータモデル構文を使用します。既存のプロジェクトをアップグレードする方法については、ドキュメントまたはこのチュートリアルビデオをご覧ください。
データモデリングへのより柔軟なアプローチ
データモデルは、すべてのPrismaプロジェクトの基盤です。これは、基となるデータベースのスキーマの基礎として機能します。
現在のデータモデルは、リレーション、テーブル/カラムの命名、システムフィールドなど、データベースレイアウトに関して独自の意見を持っています。新しいデータモデル構文は、多くの制限を取り除き、開発者がスキーマをより詳細に制御できるようにします。
データベースレイアウトのより詳細な制御
新しいデータモデル構文によって可能になるいくつかのこと
- リレーションがリレーションテーブルを使用するか、外部キーを使用するかを指定する
- モデル/フィールド名は、基となるテーブル/カラム名と異なる場合があります
- 任意のフィールドを
id
フィールドとして使用し、「独自のIDを持ち込む」 - 任意のフィールドを
createdAt
またはupdatedAt
フィールドとして使用する
マイグレーションの簡素化とイントロスペクションの改善
以前のPrismaバージョンでは、開発者はPRISMA_CONFIG
でmigrations
フラグを設定することにより、Prismaがデータベースマイグレーションを実行するかどうかを決定する必要がありました。
最新のPrismaバージョンではmigrations
フラグが削除され、開発者は常にデータベースを手動でマイグレーションするか、Prismaを使用してマイグレーションを行うかのいずれかを選択できるようになりました。
また、既存のデータベースのイントロスペクションにも多大な投資を行い、レガシーデータベースでPrismaを使用している開発者や、ある時点で手動マイグレーションを実行する必要がある開発者にとって、スムーズなワークフローを実現しました。
改善されたデータモデル構文の新機能とは?
モデル名とフィールド名を基となるテーブルとカラムにマッピングする
以前のデータモデル構文では、テーブルとカラムは常にデータモデルのモデル名とフィールド名と完全に同じ名前でした。新しい@db
ディレクティブを使用すると、基となるデータベースでテーブルとカラムがどのように呼ばれるかを制御できます。
この場合、基となるテーブルはuser
、カラムはfull_name
という名前になります。
データベーススキーマでのリレーションの表現方法を決定する
以前のデータモデルは、データベーススキーマにおけるリレーションについて独自の意見を持っていました。それは常にリレーションテーブルとして表現されるというものです。
一方では、これにより既存の任意のリレーションを余分な作業なしに多対多のリレーションに簡単に移行できます。しかし、リレーションテーブルはクエリのコストが高くなることが多いため、この柔軟性にはパフォーマンス上のペナルティが伴う可能性があります。
1対1および1対nのリレーションは外部キーを介して表現できるようになりましたが、m対nのリレーションは引き続きリレーションテーブルとして表現されます。
新しいデータモデルでは、開発者は基となるデータベースでのリレーションの表現方法を完全に制御できます。2つのオプションがあります。
- インライン参照(つまり、外部キー)を介してリレーションを表現する
- リレーションテーブルを介してリレーションを表現する
ここに2つのリレーションの例があります(1つはインライン、もう1つはリレーションテーブルを使用)。
インラインリレーションの場合、@relation(link: INLINE)
ディレクティブの配置によって、リレーションのどちらの端に外部キーが保存されるかが決まります。この例では、User
テーブルに保存されます。
任意のフィールドを id
、createdAt
、または updatedAt
として使用する
以前のデータモデルでは、開発者が一意のIDを自動生成したり、レコードの作成/最終更新日時を追跡したりする場合、予約済みのフィールドを使用する必要がありました。
新しい@id
、@createdAt
、@updatedAt
ディレクティブを使用すると、この機能をモデルの任意のフィールドに追加できるようになりました。
より柔軟なID
現在のデータモデルは、データベースレコードのグローバルに一意なIDを生成および保存するために常にCUIDを使用しています。データモデルv1.1では、カスタムIDを維持したり、他のIDタイプ(例:整数、シーケンス、UUID)を使用したりすることも可能になりました。
新しいデータモデル構文を始める
新しいデータモデルを学ぶための短いチュートリアルを2つ用意しました。
- オプションA:古いPrismaプロジェクトをアップグレードする新しいデータモデル構文へ
- オプションB:ゼロから始める新しいデータモデル構文で
より詳細なチュートリアルや既存のデータベースでの開始手順については、ドキュメントをご覧ください。
前提条件:最新のPrisma CLIをインストールする
Prisma CLIの最新バージョンをインストールするには、以下を実行します
DockerでPrismaを実行する場合、Dockerイメージを
1.31
にアップグレードする必要があります。
オプションA:古いPrismaバージョンからのアップグレード
既存のPrismaプロジェクトをアップグレードする際には、prisma introspect
を実行するだけで新しい構文のデータモデルを生成できます。正確な手順は、以下のセクションとこのビデオで例とともに説明されています。
1. 古いデータモデルのセットアップ
(古い)データモデルを使用しているPrismaプロジェクトが既に稼働中であると仮定します。
古いデータモデルを使用すると、Prismaによって基となるデータベースに以下のテーブルが作成されます
User
Profile
Post
Category
_CategoryToPost
_PostToUser
_ProfileToUser
_RelayId
各リレーションはリレーションテーブルを介して表現されます。_RelayId
テーブルは、レコードをそのIDで識別するために使用されます。古いデータモデル構文では、これらはPrismaが行う決定であり、回避することはできませんでした。
2. Prismaサーバーのアップグレード
Prismaサーバーをデプロイするために使用するDocker Composeファイルで、prismagraphql/prisma
イメージに最新の1.31
Prismaバージョンを使用していることを確認してください。例:
稼働中のPrismaサーバーをアップグレードする
3. イントロスペクションによる新しいデータモデルの生成
もし現在prisma deploy
を実行すると、古い構文のデータモデルを更新されたPrismaサーバーにデプロイしようとしているため、Prisma CLIがエラーをスローします。
これらのエラーを修正する最も簡単な方法は、イントロスペクションを介して新しい構文で書かれたデータモデルを生成することです。prisma.yml
があるディレクトリ内で以下のコマンドを実行してください。
これによりデータベースがイントロスペクトされ、新しい構文のデータモデルがdatamodel-TIMESTAMP.prisma
(例:datamodel-1554394432089.prisma
)という名前で生成されます。上記の例では、以下のデータモデルが生成されます。
4. 新しいデータモデルのデプロイ
最後のステップは、古いdatamodel.prisma
ファイルを削除し、生成されたデータモデルをdatamodel.prisma
にリネームすることです(これにより、prisma.yml
のdatamodel
プロパティが新しい構文を使用している生成ファイルを参照するようになります)。
これが完了したら、以下を実行できます。
5. データベーススキーマの最適化
イントロスペクションはデータベースレイアウトを何も変更しないため、すべてのリレーションは依然としてリレーションテーブルとして表現されます。古い1対1および1対nのリレーションを外部キーを使用するように移行する方法を学ぶには、こちらのドキュメントをご覧ください。
オプションB:ゼロから始める
既存のPrismaプロジェクトをアップグレードする方法を学んだ後、今度はゼロから始めるシンプルなセットアップについて説明します。
1. 新しいPrismaプロジェクトを作成する
まず、新しいPrismaプロジェクトをセットアップしましょう。
対話型ウィザードで、以下を選択します。
- 「新しいデータベースを作成」を選択
- 「PostgreSQL」を選択(またはお好みでMySQL)
- 好みの言語でクライアントを選択(クライアントは使用しないためオプション)
Docker経由でPrismaサーバーとデータベースを起動する前に、データベースのポートマッピングを有効にしてください。これにより、後でローカルのDBクライアント(PosticoやTablePlusなど)を使用してデータベースに接続できるようになります。
生成されたdocker-compose.yml
で、データベースのDockerイメージ構成にある以下の行のコメントを解除します。
2. データモデルの定義
新しいPrismaの機能を活用するデータモデルを定義しましょう。datamodel.prisma
を開き、内容を以下に置き換えます。
このデータモデル定義に関するいくつかの重要な点
- 各モデルは、
@db
ディレクティブを使用して、モデル名と同じで小文字に変換された名前のテーブルにマッピングされます。 - 以下のリレーションがあります
- 1対1
User
とProfile
間 - 1対多
User
とPost
間 - 多対多
Post
とCategory
間
- 1対1
- 1対1
User
とProfile
間のリレーションは、User
モデルで@relation(link: INLINE)
としてアノテーションされています。これは、リレーションが存在する場合(profile
フィールドは必須ではないため、リレーションがNULL
の場合もあります)、データベースのuser
レコードがprofile
レコードへの参照を持つことを意味します。INLINE
の代替としてTABLE
があり、その場合Prismaは専用のリレーションテーブルを介してリレーションを追跡します。 - 1対多
User
とPost
間のリレーションは、post
テーブルのauthor
カラムを介してリレーションがインラインで追跡されます。つまり、@relation(link: INLINE)
ディレクティブはPost
モデルのauthor
フィールドに推論されます。 - 多対多
Post
とCategory
間のリレーションは、PostToCategory
という専用のリレーションテーブルを介して追跡されます。このリレーションテーブルはデータモデルの一部であり、@relationTable
ディレクティブでアノテーションされています。 - 各モデルには、
@id
ディレクティブでアノテーションされたid
フィールドがあります。 User
モデルの場合、データベースは@createdAt
ディレクティブでアノテーションされたフィールドを介して、レコードが作成された日時を自動的に追跡します。Post
モデルの場合、データベースは@createdAt
および@updatedAt
ディレクティブでアノテーションされたフィールドを介して、レコードが作成および更新された日時を自動的に追跡します。
3. データモデルのデプロイ
次のステップで、Prismaはこのデータモデルを基となるデータベースにマッピングします。
Category
テーブル
インデックス
category_pkey
BTREE
TRUE
id
Post
テーブル
インデックス
post_pkey
BTREE
TRUE
id
PostToCategory
テーブル
インデックス
post_to_category_AB_unique
BTREE
TRUE
category
,post
post_to_category_B
BTREE
FALSE
post
Profile
テーブル
インデックス
profile_pkey
BTREE
TRUE
id
User
テーブル
インデックス
user_pkey
BTREE
TRUE
id
hello-datamodel$dev.user.email._UNIQUE
BTREE
TRUE
email
4. Prisma Adminでのデータの表示と編集
ここからは、プログラムでデータベースのデータにアクセスしたい場合、Prismaクライアントを使用できます。以下では、Prisma Adminを使用してデータとやり取りする方法を重点的に説明します。
TablePlusを使用してデータベースに接続し、基となるデータベーススキーマを探索する方法については、ドキュメントをご覧ください。
Prisma Adminでデータにアクセスするには、PrismaプロジェクトのAdminエンドポイント、https://:4466/_admin
にアクセスする必要があります。
ご意見とアイデアを共有してください
新しいデータモデル構文はすでにコミュニティからの多くの要望を取り入れていますが、さらに改善の余地があると考えています。例えば、このデータモデルにはまだ多列インデックスやポリモーフィックリレーションが提供されていません。
現在、既存のSDLのバリエーションとなる新しいデータモデリング言語の開発に取り組んでいます。
新しいデータモデルについてのご意見をお聞かせください。フィードバックリポジトリでissueを開くか、Spectrumでの議論に参加して、ご意見を共有してください。
次の投稿をお見逃しなく!
Prismaニュースレターに登録する