跳到主要內容

如何在 Astro 中使用 Prisma ORM

15 分鐘

簡介

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,你需要安裝一些依賴項

npm install prisma tsx --save-dev
npm install @prisma/extension-accelerate @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 提供程式

prisma/schema.prisma
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])
}

這將建立兩個模型:UserPost,它們之間存在一對多的關係。

2.3. 配置 Prisma Client 生成器

現在,執行以下命令來建立資料庫表並生成 Prisma Client

npx prisma migrate dev --name init

2.4. 填充資料庫

讓我們新增一些種子資料來填充資料庫,包含示例使用者和帖子。

prisma/ 目錄中建立一個名為 seed.ts 的新檔案

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 如何執行此指令碼

package.json
{
"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

src/lib/prisma.ts
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;
警告

我們建議使用連線池(如 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

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" },
});
};

接下來,你將從 index.astro 檔案呼叫此路由並顯示它。

3.3. 從 API 路由獲取資料

首先建立一個名為 UserWithPosts 的新型別,它結合了 UserPost 模型

src/pages/index.astro
---
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 型別

src/pages/index.astro
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://: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 型別新增到使用者,並顯示使用者的名稱

src/pages/index.astro
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://: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 型別

src/pages/index.astro
---
import type { User, Post } from "../generated/prisma/client.js";
type UserWithPosts = User & { posts: Post[] };
const response = await fetch("https://: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 之旅 我們活躍的社群。保持資訊靈通,參與進來,並與其他開發者協作

我們真誠地感謝您的參與,並期待您成為我們社群的一員!

© . This site is unofficial and not affiliated with Prisma Data, Inc.