Turso
このガイドでは、Prisma ORMとTursoの使用に関する概念について説明し、Tursoと他のデータベースプロバイダーとの共通点と相違点を説明し、Tursoと統合するようにアプリケーションを構成するプロセスを順を追って説明します。
TursoのPrisma ORMサポートは現在、早期アクセス段階です。このGitHubディスカッションでフィードバックをお寄せいただけると幸いです。
Tursoとは?
Tursoは、libSQL、つまりSQLiteのオープンソースでオープンな貢献によるフォークに基づいて構築された、エッジホスト型の分散データベースであり、データをお客様のアプリケーションに近づけ、クエリのレイテンシを最小限に抑えることができます。Tursoはリモートサーバーでホストすることもできます。
TursoのサポートはPrisma ORMバージョン5.4.2以降で早期アクセスとして利用可能です。
他のデータベースプロバイダーとの共通点
libSQLはSQLiteと100%互換性があります。libSQLはSQLiteを拡張し、以下の機能と能力を追加しています。
- レプリケーションのサポート
- 自動バックアップのサポート
- TursoをLinuxカーネルなどの他のプログラムの一部として埋め込む機能
- ユーザー定義関数をサポート
- 非同期I/Oのサポート
libSQLとSQLiteの違いの詳細については、libSQLマニフェストを参照してください。
TursoでPrisma ORMを使用する多くの側面は、他のリレーショナルデータベースでPrisma ORMを使用するのと同様です。引き続き以下が可能です。
- Prismaスキーマ言語でデータベースをモデル化する
- スキーマでPrisma ORMの既存の
sqlite
データベースコネクタを使用する - アプリケーションでPrisma Clientを使用して、Tursoのデータベースサーバーと通信する
考慮すべき相違点
TursoとSQLiteの間には、考慮すべき多くの相違点があります。TursoとPrisma ORMを使用するかどうかを決定する際には、以下の点に注意する必要があります。
- リモートおよび埋め込みSQLiteデータベース。libSQLはHTTPを使用してリモートSQLiteデータベースに接続します。libSQLは、リモートデータベースレプリカと埋め込みレプリカもサポートしています。埋め込みレプリカを使用すると、プライマリデータベースをアプリケーション内にレプリケートできます。
- スキーマの変更を行う。libSQLはHTTPを使用してリモートデータベースに接続するため、Prisma Migrateとの互換性がありません。ただし、
prisma migrate diff
を使用してスキーママigrationを作成し、TursoのCLIを使用してデータベースに変更を適用できます。
Tursoデータベースに接続してクエリを実行する方法
次のセクションでは、Tursoデータベースを作成し、データベースの認証情報を取得してデータベースに接続する方法について説明します。
データベースをプロビジョニングし、データベースの認証情報を取得する方法
データベースを管理するために、Turso CLIがインストールされていることを確認してください。
既存のデータベースがない場合は、次のコマンドを実行してデータベースをプロビジョニングできます。
turso db create turso-prisma-db
上記のコマンドは、お客様の場所に最も近いリージョンにデータベースを作成します。
データベースの接続文字列を取得するには、次のコマンドを実行します。
turso db show turso-prisma-db
次に、データベースへの接続を許可する認証トークンを作成します。
turso db tokens create turso-prisma-db
認証トークンと接続文字列で.env
ファイルを更新します。
TURSO_AUTH_TOKEN="eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
TURSO_DATABASE_URL="libsql://turso-prisma-db-user.turso.io"
Tursoデータベースへの接続方法
開始するには、driverAdapters
プレビュー機能フラグを有効にします。
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
Prisma Clientを生成します。
npx prisma generate
libSQLデータベースクライアントとlibSQLパッケージ用のPrisma ORMドライバアダプターをインストールします。
npm install @libsql/client @prisma/adapter-libsql
Prisma Clientインスタンスを更新します。
import { PrismaClient } from '@prisma/client'
import { PrismaLibSQL } from '@prisma/adapter-libsql'
import { createClient } from '@libsql/client'
const libsql = createClient({
url: `${process.env.TURSO_DATABASE_URL}`,
authToken: `${process.env.TURSO_AUTH_TOKEN}`,
})
const adapter = new PrismaLibSQL(libsql)
const prisma = new PrismaClient({ adapter })
Prisma Clientは通常どおりに使用でき、プロジェクトで完全な型安全性が確保されます。
prisma.config.ts
でドライバアダプターを介してPrisma Migrateを使用する(早期アクセス)
v6.6.0以降およびprisma.config.ts
ファイルを使用すると、prisma db push
を使用してデータベーススキーマに変更を加えることができます。
1. LibSQLドライバアダプターをインストールする
ターミナルでこのコマンドを実行します。
npm install @prisma/adapter-libsql
2. 環境変数を設定する
LibSQLアダプターをセットアップするには、いくつかのシークレットを.env
ファイルに追加する必要があります。
LIBSQL_DATABASE_URL
:Tursoデータベースインスタンスの接続URL。LIBSQL_DATABASE_TOKEN
:Tursoデータベースインスタンスのトークン。
これらを.env
ファイルに追加するか、別のシークレットストアに保存されている場合は直接使用できます。
LIBSQL_DATABASE_URL="..."
LIBSQL_DATABASE_TOKEN="..."
3. Prisma Configファイルを設定する
プロジェクトにprisma.config.ts
ファイルがあることを確認してください。次に、migrationドライバアダプターをPrismaLibSQL
を使用するように設定します。
import path from 'node:path'
import { defineConfig } from 'prisma/config'
import { PrismaLibSQL } from '@prisma/adapter-libsql'
// import your .env file
import 'dotenv/config'
type Env = {
LIBSQL_DATABASE_URL: string
LIBSQL_DATABASE_TOKEN: string
}
export default defineConfig<Env>({
earlyAccess: true,
schema: path.join('prisma', 'schema.prisma'),
migrate: {
async adapter(env) {
return new PrismaLibSQL({
url: env.LIBSQL_DATABASE_URL,
authToken: env.LIBSQL_DATABASE_TOKEN,
})
}
}
})
4. データベースを移行する
Prisma Migrateは、prisma.config.ts
で提供された構成に基づいて、リモートTursoデータベースに対してmigrationを実行するようになります。
このワークフローで最初のmigrationを作成するには、次のコマンドを実行します。
npx prisma db push
埋め込みTursoデータベースレプリカ
Tursoは埋め込みレプリカをサポートしています。Tursoの埋め込みレプリカを使用すると、プライマリのリモートデータベースのコピーをアプリケーション内に持つことができます。埋め込みレプリカは、ローカルのSQLiteデータベースと同様に動作します。データベースがアプリケーション内にあるため、データベースクエリが高速になります。
埋め込みデータベースレプリカの仕組み
アプリが最初にデータベースへの接続を確立すると、プライマリデータベースがクエリを処理します。
Tursoは、(1)アプリケーション内に埋め込みレプリカを作成し、(2)プライマリデータベースからレプリカにデータをコピーして、ローカルで利用できるようにします。
埋め込みレプリカは、後続の読み取りクエリを処理します。libSQLクライアントは、埋め込みレプリカのデータを最新の状態に保つために呼び出すことができるsync()
メソッドを提供します。
埋め込みレプリカを使用すると、データがローカルですぐに利用可能になり、アクセスが高速になるため、このセットアップは応答性の高いアプリケーションを保証します。
使い慣れている可能性のある読み取りレプリカのセットアップと同様に、書き込み操作はプライマリリモートデータベースに転送され、実行されてからすべての埋め込みレプリカに伝播されます。
- 書き込み操作の伝播はデータベースに転送されます。
- データベースは、1からの更新でサーバーに応答します。
- 書き込み操作はデータベースレプリカに伝播されます。
アプリケーションのデータニーズによって、リモートデータベースと埋め込みデータベースレプリカ間でデータを同期する必要がある頻度が決まります。たとえば、ミドルウェア関数(ExpressやFastifyなど)またはcronジョブを使用してデータを同期できます。
リモートデータベースと埋め込みレプリカ間でデータを同期する方法
Prisma ORMで埋め込みレプリカの使用を開始するには、アプリケーションにlibSQLのsync()
メソッドを追加します。以下の例は、Expressミドルウェアを使用してデータを同期する方法を示しています。
import express from 'express'
const app = express()
// ... the rest of your application code
app.use(async (req, res, next) => {
await libsql.sync()
next()
})
app.listen(3000, () => console.log(`Server ready at http://localhost:3000`))
これは、Prisma Client拡張機能として実装することもできます。以下の例は、作成、更新、または削除操作が実行された後の自動同期を示しています。
const prisma = new PrismaClient().$extends({
query: {
$allModels: {
async $allOperations({ operation, model, args, query }) {
const result = await query(args)
// Synchronize the embedded replica after any write operation
if (['create', 'update', 'delete'].includes(operation)) {
await libsql.sync()
}
return result
}
}
}
})