Skip to main content

如何将 Prisma ORM 与 Astro 结合使用

15 min

介绍

¥Introduction

Questions answered in this page
  • 如何将 Prisma 与 Astro 集成?

    ¥How to integrate Prisma with Astro?

  • 如何在 Astro 中设置 Prisma Postgres?

    ¥How to set up Prisma Postgres in Astro?

  • 如何在 Astro 页面中查询数据?

    ¥How to query data in Astro pages?

Prisma ORM 提供类型安全的数据库访问,而 Astro 则专为性能而构建。结合 Prisma Postgres,你将获得一个快速、内容优先、零冷启动和端到端速度的堆栈。

¥Prisma ORM offers type-safe database access, and Astro is built for performance. Together with Prisma Postgres, you get a fast, content-first stack with zero cold starts and end-to-end speed.

在本指南中,你将学习如何从零开始在 Astro 项目中将 Prisma ORM 与 Prisma Postgres 数据库集成。你可以在 GitHub 上找到本指南的完整示例。

¥In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in an Astro project from scratch. You can find a complete example of this guide on GitHub.

先决条件

¥Prerequisites

1. 设置你的项目

¥ Set up your project

创建一个新的 Astro 项目:

¥Create a new Astro project:

npx create-astro@latest
信息
  • 我们应该在哪里创建你的新项目?astro-prisma

    ¥Where should we create your new project? astro-prisma

  • 你希望如何启动你的新项目?Use minimal (empty) template

    ¥How would you like to start your new project? Use minimal (empty) template

  • 安装依赖?(推荐)Yes

    ¥Install dependencies? (recommended) Yes

  • 是否初始化新​​的 git 存储库?(可选)Yes

    ¥Initialize a new git repository? (optional) Yes

2. 安装和配置 Prisma

¥ Install and Configure Prisma

2.1.安装依赖

¥2.1. Install dependencies

要开始使用 Prisma,你需要安装一些依赖:

¥To get started with Prisma, you'll need to install a few dependencies:

npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @prisma/client dotenv

安装完成后,请在你的项目中初始化 Prisma:

¥Once installed, initialize Prisma in your project:

npx prisma init --db --output ../prisma/generated
信息

在设置 Prisma Postgres 数据库时,你需要回答几个问题。选择离你最近的区域,并为数据库选择一个容易记住的名称,例如 "我的 Astro 项目"

¥You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Astro Project"

这将造成:

¥This will create:

  • 一个包含 schema.prisma 文件的 prisma/ 目录

    ¥A prisma/ directory with a schema.prisma file

  • A prisma.config.ts file for configuring Prisma

  • 一个已设置 DATABASE_URL.env 文件

    ¥A .env file with a DATABASE_URL already set

2.2.定义 Prisma Schema

¥2.2. Define your Prisma Schema

prisma/schema.prisma 文件中,添加以下模型,并将生成器更改为使用 prisma-client 提供程序:

¥In the prisma/schema.prisma file, add the following models and change the generator to use the prisma-client provider:

prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../prisma/generated"
}

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])
}

这将创建两个模型:UserPost,它们之间存在一对多关系。

¥This creates two models: User and Post, with a one-to-many relationship between them.

2.3 Add dotenv to prisma.config.ts

To get access to the variables in the .env file, they can either be loaded by your runtime, or by using dotenv.Include an import for dotenv at the top of the prisma.config.ts

import 'dotenv/config'
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
},
engine: 'classic',
datasource: {
url: env('DATABASE_URL'),
},
});

2.4.配置 Prisma 客户端生成器

¥2.4. Configure the Prisma Client generator

现在,运行以下命令创建数据库表并生成 Prisma 客户端:

¥Now, run the following command to create the database tables and generate the Prisma Client:

npx prisma migrate dev --name init

2.5.种子数据库

¥2.5. Seed the database

让我们添加一些种子数据,以便用示例用户和帖子填充数据库。

¥Let's add some seed data to populate the database with sample users and posts.

prisma/ 目录中创建一个名为 seed.ts 的新文件:

¥Create a new file called seed.ts in the prisma/ directory:

prisma/seed.ts
import { PrismaClient, Prisma } from "../prisma/generated/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() {
console.log("Starting to seed...");

for (const u of userData) {
await prisma.user.upsert({
where: { email: u.email },
update: {},
create: u,
});
}

console.log("Seeding finished.");
}

main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

现在,通过更新 prisma.config.ts 来告诉 Prisma 如何运行此脚本:

¥Now, tell Prisma how to run this script by updating your prisma.config.ts:

prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
seed: `tsx prisma/seed.ts`,
},
engine: 'classic',
datasource: {
url: env('DATABASE_URL'),
},
});

运行种子脚本:

¥Run the seed script:

npx prisma db seed

打开 Prisma Studio 检查你的数据:

¥And open Prisma Studio to inspect your data:

npx prisma studio

3. 将 Prisma 集成到 Astro

¥ Integrate Prisma into Astro

3.1.创建 TypeScript 环境定义

¥3.1. Create TypeScript environment definitions

首先,在你的 src 目录中创建一个 env.d.ts 文件,以提供环境变量的 TypeScript 定义:

¥First, create an env.d.ts file in your src directory to provide TypeScript definitions for environment variables:

src/env.d.ts
interface ImportMetaEnv {
readonly DATABASE_URL: string;
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}

3.2.创建 Prisma 客户端

¥3.2. Create a Prisma Client

/src 中,创建一个 lib 目录并在其中创建一个 prisma.ts 文件。此文件将用于创建和导出你的 Prisma 客户端实例。

¥Inside of /src, create a lib directory and a prisma.ts file inside it. This file will be used to create and export your Prisma Client instance.

mkdir src/lib
touch src/lib/prisma.ts

按如下方式设置 Prisma 客户端:

¥Set up the Prisma client like this:

src/lib/prisma.ts
import { PrismaClient } from "../../prisma/generated/client";
import { withAccelerate } from "@prisma/extension-accelerate";

const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate());

export default prisma;
警告

我们建议使用连接池(例如 Prisma 加速)来高效管理数据库连接。

¥We recommend using a connection pooler (like Prisma Accelerate) to manage database connections efficiently.

如果你选择不使用 PrismaClient,请避免在长期存在的环境中全局实例化 PrismaClient。请改为按请求创建并释放客户端,以防止耗尽数据库连接。

¥If you choose not to use one, avoid instantiating PrismaClient globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.

3.3.创建 API 路由

¥3.3. Create an API route

API 路由是从 Astro 应用中的数据库获取数据的最佳方式。

¥An API route is the best way to fetch data from your database in an Astro app.

src/pages 目录中创建一个名为 api/users.ts 的新文件:

¥Create a new file called api/users.ts in the src/pages directory:

mkdir src/pages/api
touch src/pages/api/users.ts

现在,创建一个 GET 路由,从你的数据库获取 Users 数据,并确保通过将每个用户的 Posts 添加到 include 字段来包含它们:

¥Now, create a GET route that fetches the Users data from your database, making sure to include each user's Posts by adding them to the include field:

src/pages/api/users.ts
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" },
});
};

3.4.从 API 路由获取数据(推荐方法)

¥3.4. Fetch the data from the API route (Recommended Method)

Astro 建议直接导入端点函数,而不是将 fetch() 用于 HTTP 请求。这种方法更高效,并且避免了 URL 解析问题。

¥Instead of using fetch() with HTTP requests, Astro recommends importing endpoint functions directly. This approach is more efficient and avoids URL parsing issues.

首先创建一个结合了 UserPost 模型的新类型,称为 UserWithPosts

¥Start by creating a new type that combines the User and Post models called UserWithPosts:

src/pages/index.astro
---
import type { User, Post } from "../../prisma/generated/client";
import { GET } from "./api/users.ts";

type UserWithPosts = User & { posts: Post[] };

const response = await GET(Astro);
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 + Prisma</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>

你已完成!你刚刚使用 Prisma 创建了一个连接到 Prisma Postgres 数据库的 Astro 应用。以下是一些后续步骤,以及一些可帮助你开始扩展项目的资源。

¥You're done! You've just created an Astro app with Prisma that's connected to a Prisma Postgres database. Below are some next steps to explore, as well as some more resources to help you get started expanding your project.

后续步骤

¥Next Steps

现在你有一个连接到 Prisma Postgres 数据库的 Astro 应用,你可以:

¥Now that you have a working Astro app connected to a Prisma Postgres database, you can:

  • 使用更多模型和关系扩展你的 Prisma 模式

    ¥Extend your Prisma schema with more models and relationships

  • 添加创建/更新/删除路由和表单

    ¥Add create/update/delete routes and forms

  • 探索身份验证和验证

    ¥Explore authentication and validation

  • 使用 Prisma Postgres 启用查询缓存以获得更好的性能

    ¥Enable query caching with Prisma Postgres for better performance

更多信息

¥More Info


Stay connected with Prisma

Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:

We genuinely value your involvement and look forward to having you as part of our community!