シーディング
このガイドでは、Prisma ClientとPrisma ORMに統合されたシーディング機能を使用してデータベースをシーディングする方法について説明します。シーディングを使用すると、データベースに同じデータを一貫して再作成でき、以下の目的で使用できます。
- アプリケーションの起動に必要なデータ(デフォルトの言語や通貨など)をデータベースに投入する。
- 開発環境でアプリケーションを検証および使用するための基本データを提供する。これは、開発データベースのリセットが必要になることがあるPrisma Migrateを使用している場合に特に役立ちます。
Prisma ORMでデータベースをシーディングする方法
Prisma ORMに統合されたシーディング機能は、package.json
ファイルの "prisma"
キー内の "seed"
キーにコマンドを期待します。これは任意のコマンドであり、prisma db seed
はそれを実行するだけです。このガイドではデフォルトとして、プロジェクトの prisma/
フォルダ内にシードスクリプトを作成し、そのコマンドで開始することをお勧めします。
- TypeScript
- JavaScript
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
TypeScriptでは、ts-node
はデフォルトでトランスパイルと型チェックを行います。型チェックは、--transpile-only
フラグを使用して無効にできます。
例: "seed": "ts-node --transpile-only prisma/seed.ts"
これは、メモリ使用量(RAM)を削減し、シードスクリプトの実行速度を向上させるのに役立ちます。
"prisma": {
"seed": "node prisma/seed.js"
},
Prisma Migrateと統合されたシーディング
Prisma ORMでのデータベースシーディングは、手動で prisma db seed
を使用する方法と、prisma migrate reset
および(一部のシナリオでは)prisma migrate dev
で自動的に行われる方法の2通りあります。
prisma db seed
を使用すると、シードコマンドをいつ呼び出すかを*あなたが*決定します。これは、テスト設定や新しい開発環境の準備などに役立ちます。
Prisma Migrateは、以下のセクションの手順に従う限り、シードとシームレスに統合されます。Prisma Migrateが開発データベースをリセットすると、シーディングが自動的にトリガーされます。
Prisma Migrateは、以下のシナリオでデータベースをリセットし、シーディングをトリガーします。
prisma migrate reset
CLIコマンドを手動で実行した場合。prisma migrate dev
を使用するコンテキストでデータベースが対話的にリセットされた場合(例:マイグレーション履歴の競合やデータベーススキーマのずれの結果として)。- データベースが
prisma migrate dev
によって実際に作成された場合(以前に存在しなかったため)。
シーディングなしで prisma migrate dev
または prisma migrate reset
を使用したい場合は、--skip-seed
フラグを渡すことができます。
シードスクリプトの例
ここでは、さまざまな状況に応じた特定のシードスクリプトをいくつか提案します。これらを自由にカスタマイズすることもできますが、ここに示されているとおりに使用することもできます。
TypeScriptまたはJavaScriptでデータベースをシーディングする
- TypeScript
- JavaScript
-
seed.ts
という名前の新しいファイルを作成します。これは、プロジェクトのフォルダ構造内のどこにでも配置できます。以下の例では、/prisma
フォルダに配置しています。 -
seed.ts
ファイルで、Prisma Clientをインポートし、初期化してレコードを作成します。例として、User
およびPost
モデルを持つ以下のPrismaスキーマを挙げます。schema.prismamodel User {
id Int @id @default(autoincrement())
email String @unique
name String
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean
user User @relation(fields: [userId], references: [id])
userId Int
}seed.ts
ファイルで新しいユーザーと投稿をいくつか作成しますseed.tsimport { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@prisma.io' },
update: {},
create: {
email: 'alice@prisma.io',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://prisma.dokyumento.jp/nextjs',
published: true,
},
},
},
})
const bob = await prisma.user.upsert({
where: { email: 'bob@prisma.io' },
update: {},
create: {
email: 'bob@prisma.io',
name: 'Bob',
posts: {
create: [
{
title: 'Follow Prisma on Twitter',
content: 'https://twitter.com/prisma',
published: true,
},
{
title: 'Follow Nexus on Twitter',
content: 'https://twitter.com/nexusgql',
published: true,
},
],
},
},
})
console.log({ alice, bob })
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
}) -
typescript
、ts-node
、および@types/node
の開発依存関係を追加しますnpm install -D typescript ts-node @types/node
-
prisma.seed
フィールドをpackage.json
ファイルに追加しますpackage.json{
"name": "my-project",
"version": "1.0.0",
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
"devDependencies": {
"@types/node": "^14.14.21",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
}
}プロジェクトによっては、コンパイルオプションの追加が必要になる場合があります。例えば、Next.jsを使用している場合は、以下のようにシードスクリプトを設定します。
package.json"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
}, -
データベースをシーディングするには、
db seed
CLIコマンドを実行しますnpx prisma db seed
-
seed.js
という名前の新しいファイルを作成します。これは、プロジェクトのフォルダ構造内のどこにでも配置できます。以下の例では、/prisma
フォルダに配置しています。 -
seed.js
ファイルで、Prisma Clientをインポートし、初期化してレコードを作成します。例として、User
およびPost
モデルを持つ以下のPrismaスキーマを挙げます。schema.prismagenerator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean
user User @relation(fields: [userId], references: [id])
userId Int
}seed.js
ファイルで新しいユーザーと投稿をいくつか作成しますseed.jsconst { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@prisma.io' },
update: {},
create: {
email: 'alice@prisma.io',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://prisma.dokyumento.jp/nextjs',
published: true,
},
},
},
})
const bob = await prisma.user.upsert({
where: { email: 'bob@prisma.io' },
update: {},
create: {
email: 'bob@prisma.io',
name: 'Bob',
posts: {
create: [
{
title: 'Follow Prisma on Twitter',
content: 'https://twitter.com/prisma',
published: true,
},
{
title: 'Follow Nexus on Twitter',
content: 'https://twitter.com/nexusgql',
published: true,
},
],
},
},
})
console.log({ alice, bob })
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
}) -
prisma.seed
をpackage.json
ファイルに追加しますpackage.json{
"name": "my-project",
"version": "1.0.0",
"prisma": {
"seed": "node prisma/seed.js"
}
} -
データベースをシーディングするには、
db seed
CLIコマンドを実行しますnpx prisma db seed
生のSQLクエリでデータベースをシーディングする
生のSQLクエリを使用してデータベースにデータを投入することもできます。
その目的でプレーンテキストの .sql
ファイル(データダンプなど)を使用することもできますが、生のクエリが短い場合は、データベース接続文字列を処理したり psql
のようなバイナリに依存関係を作成したりする手間が省けるため、seed.js
ファイルに配置する方が簡単な場合が多いです。
上記の schema.prisma
に追加データをシーディングするには、seed.js
(または seed.ts
) ファイルに以下を追加します
async function rawSql() {
const result = await prisma.$executeRaw`INSERT INTO "User" ("id", "email", "name") VALUES (3, 'foo@example.com', 'Foo') ON CONFLICT DO NOTHING;`
console.log({ result })
}
そして、この関数をファイルの末尾に向かって以下の変更のように、プロミス呼び出しにチェーンします
main()
.then(rawSql)
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
あらゆる言語(Bashスクリプトを使用)でデータベースをシーディングする
TypeScriptとJavaScriptに加えて、Bashスクリプト(seed.sh
)を使用して、GoやプレーンなSQLなどの他の言語でデータベースをシーディングすることもできます。
- Go
- SQL
以下の例は、seed.sh
と同じフォルダにあるGoスクリプトを実行します。
#!/bin/sh
# -e Exit immediately when a command returns a non-zero status.
# -x Print commands before they are executed
set -ex
# Seeding command
go run ./seed/
以下の例は、psql を使用して seed.sh
と同じフォルダにあるSQLスクリプトを実行します。
#!/bin/sh
# -e Exit immediately when a command returns a non-zero status.
# -x Print commands before they are executed
set -ex
# Seeding command
psql file.sql
ユーザー定義引数
この機能はバージョン4.15.0以降で利用可能です。
prisma db seed
を使用すると、シードファイルでカスタム引数を定義し、それを prisma db seed
コマンドに渡すことができます。例えば、異なる環境に異なるデータをシーディングしたり、一部のテーブルに部分的にデータをシーディングしたりするために独自の引数を定義できます。
異なる環境に異なるデータをシーディングするためのカスタム引数を定義するシードファイルの例を以下に示します
import { parseArgs } from 'node:util'
const options = {
environment: { type: 'string' },
}
async function main() {
const {
values: { environment },
} = parseArgs({ options })
switch (environment) {
case 'development':
/** data for your development */
break
case 'test':
/** data for your test environment */
break
default:
break
}
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
その後、prisma db seed
を使用する際に、区切り文字 — --
— を追加し、その後にカスタム引数を続けることで、environment
引数を提供できます。
npx prisma db seed -- --environment development
さらに進む
ここに、開発ワークフローでPrisma ORMと統合してデータベースをシーディングできるその他のツールの非網羅的なリストを示します