Prisma@SQLパッケージ¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. Prismaの仕組み¶
PrismaClient (JavaScriptパッケージ) は、クエリエンジン (バイナリ) に接続リクエストを送信する。
クエリエンジンはコネクションプールを作成し、プール内のコネクションを使用してDBに接続する。
コネクションが維持されている間、これを再利用して複数のクエリを実行する。
PrismaClientは、クエリエンジンに切断リクエストを送信する。
クエリエンジンは、データベースとのコネクションを破棄する。
02. セットアップ¶
アップグレード¶
@prisma/client
パッケージとprisma
パッケージの両方をアップグレードする必要がある。
$ yarn upgrade @prisma/client@<バージョン>
$ yarn upgrade prisma<バージョン>
02. コマンド¶
generate¶
Prismaスキーマからクライアントを作成する。
クライアントを使用して、データベースに接続できる。
マイグレーションや初期データを挿入前に必要である。
$ yarn prisma generate
✔ Generated Prisma Client (4.16.2 | library) to ./node_modules/@prisma/client in 177ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
migrate¶
▼ dev¶
ローカル環境用のマイグレーションを実行する。
$ prisma migrate dev
▼ deploy¶
本番環境用のマイグレーションを実行する。
$ prisma migrate deploy
▼ reset¶
初期の状態まで、全てロールバックする。
--force
オプションで警告を無視できる。
$ prisma migrate reset --force
db¶
▼ seed¶
ローカル環境用の初期データを挿入する。
$ yarn prisma db seed
03. スキーマ¶
datasource¶
▼ datasourceとは¶
データベース情報を設定する。
▼ url¶
プロトコル名として、mysql
やpostgresql
を設定できる。
datasource db {
provider = "<プロトコル名>"
// 例:mysql://user:password@<AWS Auroraクラスターのリーダーエンドポイント>:3306/foo
url = "<プロトコル名>://<DBユーザー>:<DBパスワード>@<DBホスト>:<ポート番号>/<DB名>?schema=public&connection_limit=30&pool_timeout=60"
}
注意点として、DBパスワードに特殊記号が含まれている場合、URLエンコードする必要がある。
$ alias urldecode='python3 -c "import sys, urllib.parse as ul; \
print(ul.unquote_plus(sys.argv[1]))"'
$ urldecode 'q+werty%3D%2F%3B'
q werty=/;
$ alias urlencode='python3 -c "import sys, urllib.parse as ul; \
print (ul.quote_plus(sys.argv[1]))"'
$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
▼ urlパラメーター¶
URLのパラメーターとして、以下などを設定できる。
- コネションプールのコネクション上限数 (
connection_limit
) - コネクションプール内のコネクションが空くまでの待機時間 (
pool_timeout
)
generator¶
generator client {
provider = "prisma-client-js"
engineType = "library"
}
04. PrismaClient¶
$transaction¶
▼ $transaction¶
複数のクエリ処理を実行するトランザクションを定義する。
import {PrismaClient} from "@prisma/client";
const prisma = new PrismaClient();
function transfer(from: string, to: string, amount: number) {
// トランザクション
return prisma.$transaction(async (tx) => {
// CRUD処理
const sender = await tx.account.update({
data: {
balance: {
decrement: amount,
},
},
where: {
email: from,
},
});
if (sender.balance < 0) {
throw new Error(`${from} doesn't have enough to send ${amount}`);
}
// CRUD処理
const recipient = await tx.account.update({
data: {
balance: {
increment: amount,
},
},
where: {
email: to,
},
});
return recipient;
});
}
async function main() {
// $transaction関数の実行をtry-catchブロックで囲む
try {
await transfer("alice@prisma.io", "bob@prisma.io", 100);
await transfer("alice@prisma.io", "bob@prisma.io", 100);
} catch (err) {}
}
main();
▼ オプション¶
import {PrismaClient} from '@prisma/client'
// トランザクションのオプションはトランザクション全体で統一する
let prismaClientOption = {
// データを取得するまでのタイムアウト値 (デフォルトは2000ms)
transactionOptions: {
// データを取得するまでのタイムアウト値 (デフォルトは2000ms)
maxWait: 5000,
// ロールバックを含めて全体が完了するまでのタイムアウト値 (デフォルトは5000ms)
timeout: 10000,
// トランザクションの分離レベル
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
}
}
// Prismaクライアントに設定する
const prisma = new PrismaClient(prismaClientOption)
function transfer(...) {
return prisma.$transaction(
async (tx) => {
// CRUD処理
})
}
async function main() {
try {
await transfer(...)
} catch (err) {
}
}
main()
import {PrismaClient} from '@prisma/client'
const prisma = new PrismaClient()
let prismaClientOption = {
// データを取得するまでのタイムアウト値 (デフォルトは2000ms)
transactionOptions: {
// データを取得するまでのタイムアウト値 (デフォルトは2000ms)
maxWait: 5000,
// ロールバックを含めて全体が完了するまでのタイムアウト値 (デフォルトは5000ms)
timeout: 10000,
// トランザクションの分離レベル
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
}
}
function transfer(...) {
return prisma.$transaction(
async (tx) => {
// CRUD処理
},
// トランザクションに個別に設定する
prismaClientOption
)
}
async function main() {
try {
await transfer(...)
} catch (err) {
}
}
main()