Skip to main content

如何将 Prisma ORM 与 SvelteKit 结合使用

15 min

介绍

¥Introduction

Prisma ORM 通过类型安全的查询简化了数据库访问,与 SvelteKit 配合使用时,可创建健壮且可扩展的全栈架构。

¥Prisma ORM simplifies database access with type-safe queries, and when paired with SvelteKit, it creates a robust and scalable full-stack architecture.

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

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

先决条件

¥Prerequisites

1. 设置你的项目

¥ Set up your project

你将使用 Svelte CLI 而不是 npx create svelte@latest。此 CLI 提供了更具交互性的设置,并内置了对 ESLint 和 Prettier 等流行工具的支持。

¥You'll be using Svelte CLI instead of npx create svelte@latest. This CLI provides a more interactive setup and built-in support for popular tooling like ESLint and Prettier

创建一个新的 Svelte 项目:

¥Create a new Svelte project:

npx sv create sveltekit-prisma

它会提示你自定义设置。以下是你将选择的选项:

¥It will prompt you to customize your setup. Here are the options you'll choose:

信息
  • 你想要哪个模板?SvelteKit minimal

    ¥Which template would you like? SvelteKit minimal

  • 是否使用 TypeScript 添加类型检查?Yes, using TypeScript syntax

    ¥Add type checking with TypeScript? Yes, using TypeScript syntax

  • 你想在项目中添加什么?

    ¥What would you like to add to your project?

    • prettier

    • eslint

  • 你想使用哪个软件包管理器来安装依赖?npm

    ¥Which package manager do you want to install dependencies with? npm

设置完成后,导航到你的项目并启动开发服务器:

¥Once the setup completes, navigate into your project and start the development server:

cd sveltekit-prisma
npm run dev

就是这样!Svelte 使启动和运行变得非常简单。此时,你的项目已准备好集成 Prisma 并连接到 Prisma Postgres 数据库。

¥That's it! Svelte makes it a very simple process to get up and running. At this point, your project is ready to integrate Prisma and connect to a Prisma Postgres database.

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

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

¥Once installed, initialize Prisma in your project:

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

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

¥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 SvelteKit Project"

这将造成:

¥This will create:

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

    ¥A prisma directory with a schema.prisma file.

  • 一个 Prisma Postgres 数据库。

    ¥A Prisma Postgres database.

  • 一个位于项目根目录、包含 DATABASE_URL 文件的 .env 文件。

    ¥A .env file containing the DATABASE_URL at the project root.

  • 用于生成的 Prisma 客户端的 output 目录,用作 src/generated/prisma

    ¥An output directory for the generated Prisma Client as src/generated/prisma.

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 = "../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,它们之间存在一对多关系。

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

2.3.配置 Prisma 客户端生成器

¥2.3. 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.4.种子数据库

¥2.4. Seed the database

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

¥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 "../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 如何运行此脚本:

¥Now, tell Prisma how to run this script by updating your package.json:

package.json
{
"name": "sveltekit-prisma",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
// ...
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
"devDependencies": {
// ...
},
"dependencies": {
// ...
}
}

运行种子脚本:

¥Run the seed script:

npx prisma db seed

打开 Prisma Studio 检查你的数据:

¥And open Prisma Studio to inspect your data:

npx prisma studio

3. 将 Prisma 集成到 SvelteKit

¥ Integrate Prisma into SvelteKit

3.1.创建 Prisma 客户端

¥3.1. Create a Prisma Client

在你的 /src/lib 目录中,将 index.ts 重命名为 prisma.ts。此文件将用于创建和导出你的 Prisma 客户端实例。

¥Inside your /src/lib directory, rename index.ts to prisma.ts. This file will be used to create and export your Prisma Client instance.

提示

可以使用 $lib 别名从任何地方访问 src/lib 中的文件。

¥Files in src/lib can be accessed from anywhere using the $lib alias.

DATABASE_URL 存储在 .env 文件中。要访问它,你需要从 $env/static/private 命名空间导入它。

¥The DATABASE_URL is stored in the .env file. To access it, you'll need to import it from the $env/static/private namespace.

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

¥Set up the Prisma client like this:

src/lib/prisma.ts
import { PrismaClient } from '../generated/prisma/client.js';
import { DATABASE_URL } from '$env/static/private';
import { withAccelerate } from '@prisma/extension-accelerate';

const prisma = new PrismaClient({
datasourceUrl: 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.2.创建服务器路由

¥3.2. Create a server route

要从服务器端的数据库获取数据,请在 routes 目录中创建一个 +page.server.ts 文件。此文件应导出一个 load 函数,该函数在你的页面渲染之前在服务器上运行。

¥To fetch data from the database on the server side, create a +page.server.ts file in your routes directory. This file should export a load function, which runs on the server before your page renders.

在基本 load 函数中使用 findMany() 方法获取用户列表。

¥Use the findMany() method within a basic load function to get a list of users.

像这样更新你的 +page.server.ts 文件:

¥Update your +page.server.ts file like this:

src/routes/+page.server.ts
import prisma from '$lib/prisma';

export async function load() {
const users = await prisma.user.findMany({});
return {
users
};
}

此时,你只能直接获取 User 模型上的数据 - 尚未包含帖子之类的关系。

¥At this point, you're only getting data directly on the User model — no relations like posts are included yet.

为了获取每个用户的帖子,我们可以使用 include 选项扩展查询。这会告诉 Prisma 将相关的 Posts 表加入结果中。

¥To also fetch each user's posts, we can expand the query using the include option. This tells Prisma to join the related Posts table in the result.

像这样更新你的 findMany() 调用:

¥Update your findMany() call like this:

src/routes/+page.server.ts
import prisma from '$lib/prisma';

export async function load() {
const users = await prisma.user.findMany({
include: {
posts: true
}
});

return {
users
};
}

现在,结果中的每个用户都将包含一个 posts 数组。

¥Now, every user in the result will also include a posts array.

3.3.填充页面

¥3.3. Populate the page

src/routes/+page.svelte 中,将文件精简到最基本的内容,并添加一个 <script> 片段。文件应如下所示:

¥In src/routes/+page.svelte, strip the file down to the basics and add a <script> fragment. The file should look like this:

src/routes/+page.svelte
<script lang="ts">
</script>

<h1>SvelteKit + Prisma</h1>

我们需要获取从 +page.server.ts 导出的数据:

¥We need to grab the data exported from +page.server.ts:

src/routes/+page.svelte
<script lang="ts">
let { data } = $props();
</script>

<h1>SvelteKit + Prisma</h1>

现在我们有了数据,让我们使用 Svelte 的 each 块来映射用户及其帖子:

¥Now that we have the data, let's map through the users and their posts with Svelte's each block:

src/routes/+page.svelte
<script lang="ts">
let { data } = $props();
</script>

<h1>SvelteKit + Prisma</h1>

{#each data.users as user}
<h2>{user.name}</h2>
{#each user.posts as post}
<ul>
<li><a href={post.content}>{post.title}</a></li>
</ul>
{/each}
{/each}

你已完成!你刚刚使用 Prisma ORM 创建了一个 SvelteKit 应用。以下是一些后续步骤,以及一些可帮助你开始扩展项目的资源。

¥You're done! You've just created a SvelteKit app with Prisma ORM. 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 数据库的可运行 SvelteKit 应用,你可以:

¥Now that you have a working SvelteKit 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!