如何在 Astro 中使用 Prisma ORM
简介
Prisma ORM 提供类型安全的数据库访问,而 Astro 则以性能为核心。结合 Prisma Postgres,你将获得一个快速、内容优先的堆栈,零冷启动且端到端高速。
在本指南中,你将从头开始学习如何将 Prisma ORM 与 Prisma Postgres 数据库集成到 Astro 项目中。你可以在 GitHub 上找到本指南的完整示例。
先决条件
1. 设置你的项目
创建一个新的 Astro 项目
npx create-astro@latest
- 你的新项目应该创建在哪里?
astro-prisma
- 你希望如何开始你的新项目?
使用最小(空)模板
- 安装依赖项?(推荐)
是
- 初始化新的 git 仓库?(可选)
是
2. 安装并配置 Prisma
2.1. 安装依赖项
要开始使用 Prisma,你需要安装一些依赖项
- Prisma Postgres (推荐)
- 其他数据库
npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @prisma/client
npm install prisma tsx --save-dev
npm install @prisma/client
安装完成后,在你的项目中初始化 Prisma
npx prisma init --db --output ../src/generated/prisma
在设置 Prisma Postgres 数据库时,你需要回答一些问题。选择离你位置最近的区域,并为你的数据库取一个好记的名字,比如“我的 Astro 项目”
这将创建
- 一个包含
schema.prisma
文件的prisma/
目录 - 一个已设置
DATABASE_URL
的.env
文件
2.2. 定义你的 Prisma Schema
在 prisma/schema.prisma
文件中,添加以下模型并更改生成器以使用 prisma-client
提供程序
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
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 @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}
这将创建两个模型:User
和 Post
,它们之间存在一对多的关系。
2.3. 配置 Prisma Client 生成器
现在,运行以下命令来创建数据库表并生成 Prisma Client
npx prisma migrate dev --name init
2.4. 填充数据库
让我们添加一些种子数据来填充数据库,包含示例用户和帖子。
在 prisma/
目录中创建一个名为 seed.ts
的新文件
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
const prisma = new PrismaClient();
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
现在,通过更新 package.json
来告诉 Prisma 如何运行此脚本
{
"name": "extinct-eclipse-minimal",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@prisma/client": "^6.7.0",
"@prisma/extension-accelerate": "^1.3.0",
"astro": "^5.7.10"
},
"devDependencies": {
"prisma": "^6.7.0",
"tsx": "^4.19.4"
}
}
运行种子脚本
npx prisma db seed
并打开 Prisma Studio 来检查你的数据
npx prisma studio
3. 将 Prisma 集成到 Astro 中
3.1. 创建 Prisma Client
在 /src
内部,创建一个 lib
目录并在其中创建一个 prisma.ts
文件。此文件将用于创建和导出你的 Prisma Client 实例。
mkdir src/lib
touch src/lib/prisma.ts
像这样设置 Prisma Client
- Prisma Postgres (推荐)
- 其他数据库
import { PrismaClient } from "../generated/prisma/client.js";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate());
export default prisma;
import { PrismaClient } from "../generated/prisma/client.js";
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
})
export default prisma;
我们建议使用连接池(如 Prisma Accelerate)来高效管理数据库连接。
如果你选择不使用连接池,请避免在长期运行的环境中全局实例化 PrismaClient
。相反,请为每个请求创建和销毁客户端,以防止耗尽你的数据库连接。
3.2. 创建 API 路由
API 路由是在 Astro 应用中从数据库获取数据的最佳方式。
在 src/pages
目录中创建一个名为 api/users.ts
的新文件
mkdir src/pages/api
touch src/pages/api/users.ts
现在,创建一个 GET 路由,从数据库中获取 Users
数据,确保通过将其添加到 include
字段来包含每个用户的 Posts
import type { APIRoute } from "astro";
import prisma from "../../lib/prisma";
export const GET: APIRoute = async () => {
const users = await prisma.user.findMany({
include: { posts: true },
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
};
接下来,你将从 index.astro
文件调用此路由并显示它。
3.3. 从 API 路由获取数据
首先创建一个名为 UserWithPosts
的新类型,它结合了 User
和 Post
模型
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>
从 API 路由获取数据并将其类型设置为你刚刚创建的 UserWithPosts
类型
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("http://localhost:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>
3.4. 显示数据
现在,前置变量在整个文件中可用,你可以显示用户列表。
在 <h1>
标签下方,遍历 users
数组,将 UserWithPosts
类型添加到用户,并显示用户的名称
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("http://localhost:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro + Prisma</h1>
{users.map((user: UserWithPosts) => (
<li>
<h2>{user.name}</h2>
</li>
))}
</body>
</html>
最后,在各自的 User
下方显示 Posts
并设置 Post
类型
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("http://localhost:4321/api/users");
const users: UserWithPosts[] = await response.json();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro + Prisma</h1>
<ul>
{users.map((user: UserWithPosts) => (
<li>
<h2>{user.name}</h2>
<ul>
{user.posts.map((post: Post) => (
<li>{post.title}</li>
))}
</ul>
</li>
))}
</ul>
</body>
</html>
你完成了!你刚刚创建了一个 Astro 应用,其中 Prisma 连接到 Prisma Postgres 数据库。下面是一些可以探索的下一步,以及一些更多资源,可帮助你开始扩展项目。
下一步
现在你已经拥有一个连接到 Prisma Postgres 数据库的 Astro 应用,你可以
- 使用更多模型和关系扩展你的 Prisma schema
- 添加创建/更新/删除路由和表单
- 探索认证和验证
- 使用 Prisma Postgres 启用查询缓存以获得更好的性能
更多信息
与 Prisma 保持联系
通过以下方式与我们建立联系,继续你的 Prisma 之旅 我们活跃的社区。保持信息灵通,参与进来,并与其他开发者协作
- 在 X 上关注我们 获取公告、直播活动和实用技巧。
- 加入我们的 Discord 提问、与社区交流并获得积极的对话支持。
- 在 YouTube 上订阅 获取教程、演示和直播。
- 在 GitHub 上参与 通过为仓库加星、报告问题或贡献问题。