跳转到正文

在 Cloudflare Workers 上使用 Prisma ​

Prisma ORM 提供现代而可靠的数据库交互工具。将它与 Hono 和 Cloudflare Workers 搭配使用,可以在边缘部署高性能的无服务器应用。

本指南介绍在 Hono 中使用 Prisma ORM 的两种不同方式:

两种方式各有优势,你可以选择最适合项目需求的一种。

使用 Prisma Postgres ​

Prisma Postgres 是基于 unikernel 构建的托管式无服务器 PostgreSQL 数据库,支持连接池、缓存和查询优化建议等功能。它提供较为充裕的免费额度,适合初期开发、测试和个人项目。

1. 安装 Prisma 和所需依赖 ​

在 Hono 项目中安装 Prisma:

bash
npm i prisma --save-dev

安装 Prisma Postgres 所需的 Prisma 客户端扩展:

sh
npm i @prisma/extension-accelerate

使用 Prisma Postgres 实例初始化 Prisma:

bash
npx prisma@latest init --db

如果还没有 Prisma Data Platform 账户,或者尚未登录,命令会提示你使用可用的身份验证提供商登录。浏览器窗口会打开,你可以登录或创建账户。完成后返回 CLI。

登录后(或已经登录时),CLI 会提示你选择项目名称和数据库区域。

命令执行结束后,会创建:

  • 平台控制台中的项目,其中包含 Prisma Postgres 数据库实例。
  • 包含 schema.prisma 的 prisma 文件夹,你将在此文件中定义数据库模式。
  • 项目根目录中的 .env 文件,其中包含 Prisma Postgres 数据库 URL:DATABASE_URL=<your-prisma-postgres-database-url>。

创建 .dev.vars 文件,并将 DATABASE_URL 存入其中:

bash
DATABASE_URL="your_prisma_postgres_url"

保留 .env 文件,以便之后 Prisma CLI 执行迁移、生成 Prisma Client 或打开 Prisma Studio 时访问它。

2. 在项目中配置 Prisma ​

现在,打开 schema.prisma 文件并定义数据库模式中的模型。例如,可以添加 User 模型:

ts
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id  Int @id @default(autoincrement())
  email String
  name 	String
}

使用 Prisma Migrate 将变更应用到数据库:

bash
npx prisma migrate dev

创建下面这样的函数,以便稍后在项目中使用:

ts
import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'

export const getPrisma = (database_url: string) => {
  const prisma = new PrismaClient({
    datasourceUrl: database_url,
  }).$extends(withAccelerate())
  return prisma
}

以下是在项目中使用该函数的示例:

ts
import { Hono } from 'hono'
import { sign, verify } from 'hono/jwt'
import { getPrisma } from '../usefulFun/prismaFun'

// Create the main Hono app
const app = new Hono<{
  Bindings: {
    DATABASE_URL: string
    JWT_SECRET: string
  }
  Variables: {
    userId: string
  }
}>()

app.post('/', async (c) => {
  // Now you can use it wherever you want
  const prisma = getPrisma(c.env.DATABASE_URL)
})

如果希望将自己的数据库与 Prisma ORM 搭配使用,同时利用连接池和边缘缓存,可以启用 Prisma Accelerate。有关项目配置的详情,请参阅 Prisma Accelerate。

使用 Prisma 驱动适配器 ​

Prisma 可以通过 driverAdapters 与 D1 数据库配合使用。前提是安装 Prisma,并集成 Wrangler,将其与 Hono 项目绑定。Hono、Prisma 和 Cloudflare D1 的文档分别维护,缺少完整精确的逐步说明,因此这里提供一个示例项目。

配置 Prisma ​

Prisma 和 D1 使用 Wrangler 中的绑定,通过适配器建立连接。

bash
npm install prisma --save-dev
npx prisma init
npm install @prisma/client
npm install @prisma/adapter-d1

之后,Prisma 会为数据库生成模式;请在 prisma/schema.prisma 中定义一个简单模型,并记得修改适配器。

prisma/schema.prisma
ts
generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters"] // change from default
}

datasource db {
  provider = "sqlite" // d1 is sql base database
  url      = env("DATABASE_URL")
}

// Create a simple model database
model User {
  id    String @id  @default(uuid())
  email String  @unique
  name  String?
}

D1 数据库 ​

如果已经准备好 D1 数据库,可以跳过此步骤;否则,请创建一个,具体方法可参阅这里。

bash
npx wrangler d1 create __DATABASE_NAME__ // change it with yours

确保数据库已在 wrangler.toml 中配置绑定。

wrangler.toml
toml
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "__DATABASE_NAME__"
database_id = "DATABASE ID"

Prisma Migrate ​

此命令执行 Prisma 迁移,并更新本地或远程的 D1 数据库。

bash
npx wrangler d1 migrations create __DATABASE_NAME__ create_user_table # will generate migration folder and sql file

// for generate sql statement

npx prisma migrate diff \
  --from-empty \
  --to-schema-datamodel ./prisma/schema.prisma \
  --script \
  --output migrations/0001_create_user_table.sql

将数据库模型迁移到 D1。

bash
npx wrangler d1 migrations apply __DATABASE_NAME__ --local
npx wrangler d1 migrations apply __DATABASE_NAME__ --remote
npx prisma generate

配置 Prisma Client ​

为了通过 Prisma 查询 D1 数据库,需要使用以下命令添加类型:

bash
npx wrangler types

这会生成 worker-configuration.d.ts 文件。

Prisma 客户端 ​

要全局使用 Prisma,请创建 lib/prismaClient.ts 文件,并放入如下代码。

ts
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'

const prismaClients = {
  async fetch(db: D1Database) {
    const adapter = new PrismaD1(db)
    const prisma = new PrismaClient({ adapter })
    return prisma
  },
}

export default prismaClients

将 Hono 与 Wrangler 环境值绑定:

ts
import { Hono } from 'hono'
import prismaClients from '../lib/prismaClient'

type Bindings = {
  MY_KV: KVNamespace
  DB: D1Database
}

const app = new Hono<{ Bindings: Bindings }>() // binding env value

在 Hono 路由中的使用示例:

ts
import { Hono } from 'hono'
import prismaClients from '../lib/prismaClient'

type Bindings = {
  MY_KV: KVNamespace
  DB: D1Database
}
const app = new Hono<{ Bindings: Bindings }>()

app.get('/', async (c) => {
  const prisma = await prismaClients.fetch(c.env.DB)
  const users = await prisma.user.findMany()
  console.log('users', users)
  return c.json(users)
})

export default app

这会在 / 路由返回所有用户,可以使用 Postman 或 Thunder Client 查看结果。

资源 ​

可以使用以下资源进一步完善应用:

基于 MIT 许可证发布。