|
| 1 | +--- |
| 2 | +title: Prisma Postgres 与 Astro |
| 3 | +description: 使用 Prisma Postgres 为你的 Astro 项目添加无服务器 Postgres 数据库 |
| 4 | +sidebar: |
| 5 | + label: Prisma Postgres |
| 6 | +type: backend |
| 7 | +service: Prisma Postgres |
| 8 | +stub: false |
| 9 | +i18nReady: true |
| 10 | +--- |
| 11 | + |
| 12 | +import ReadMore from '~/components/ReadMore.astro'; |
| 13 | + |
| 14 | +[Prisma Postgres](https://www.prisma.io/) 是专为现代 Web 应用构建的完全托管、无服务器的 Postgres 数据库。 |
| 15 | + |
| 16 | +## 通过 Prisma ORM 连接(推荐) |
| 17 | + |
| 18 | +推荐使用 [Prisma ORM](https://www.prisma.io/orm) 连接你的 Prisma Postgres 数据库。它提供类型安全查询、迁移和全局性能优化。 |
| 19 | + |
| 20 | +### 前提条件 |
| 21 | +- 一个已安装适配器并支持 [按需渲染(SSR)](/zh-cn/guides/on-demand-rendering/)的 Astro 项目。 |
| 22 | + |
| 23 | +### 安装依赖并初始化 Prisma |
| 24 | + |
| 25 | +运行以下命令安装所需的 Prisma 依赖项: |
| 26 | + |
| 27 | +```bash |
| 28 | +npm install prisma tsx --save-dev |
| 29 | +npm install @prisma/extension-accelerate @prisma/client |
| 30 | +``` |
| 31 | + |
| 32 | +安装完成后,使用以下命令在项目中初始化 Prisma: |
| 33 | + |
| 34 | +```bash |
| 35 | +npx prisma init --db --output ../src/generated/prisma |
| 36 | +``` |
| 37 | + |
| 38 | +设置 Prisma Postgres 数据库时,你需要回答几个问题。选择离你位置最近的区域,并为数据库取一个容易记住的名称,例如“我的 Astro 项目”。 |
| 39 | + |
| 40 | +这将创建: |
| 41 | +- 一个包含 `schema.prisma` 文件的 `prisma/` 目录 |
| 42 | +- 一个已设置好 `DATABASE_URL` 的 `.env` 文件 |
| 43 | + |
| 44 | +### 定义模型 |
| 45 | + |
| 46 | +即使你还不需要任何特定的数据模型,Prisma 仍要求在模式中至少定义一个模型,以便生成客户端并应用迁移。 |
| 47 | + |
| 48 | +以下示例将 `Post` 模型定义为占位符。将此模型添加到你的架构中即可开始使用。之后你可以放心地删除或用反映你实际数据的模型替换它。 |
| 49 | + |
| 50 | +在你的 `prisma/schema.prisma` 文件中,将生成器提供程序从 `prisma-client-js` 更新为 `prisma-client`: |
| 51 | + |
| 52 | +```prisma title="prisma/schema.prisma" {2} ins={11-16} |
| 53 | +generator client { |
| 54 | + provider = "prisma-client" |
| 55 | + output = "../src/generated/prisma" |
| 56 | +} |
| 57 | +
|
| 58 | +datasource db { |
| 59 | + provider = "postgresql" |
| 60 | + url = env("DATABASE_URL") |
| 61 | +} |
| 62 | +
|
| 63 | +model Post { |
| 64 | + id Int @id @default(autoincrement()) |
| 65 | + title String |
| 66 | + content String? |
| 67 | + published Boolean @default(false) |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +在 [Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-schema) 参考文档中了解更多关于配置 Prisma ORM 设置的信息。 |
| 72 | + |
| 73 | +### 生成迁移文件 |
| 74 | + |
| 75 | +运行以下命令创建数据库表并根据你的模式创建 Prisma 客户端。这还将创建包含迁移历史记录文件的 `prisma/migrations/` 目录。 |
| 76 | + |
| 77 | +```bash |
| 78 | +npx prisma migrate dev --name init |
| 79 | +``` |
| 80 | + |
| 81 | +### 创建 Prisma 客户端 |
| 82 | + |
| 83 | +在 `/src/lib` 目录中,创建一个 `prisma.ts` 文件。该文件将初始化并导出你的 Prisma 客户端实例,以便你可以在整个 Astro 项目中查询数据库。 |
| 84 | + |
| 85 | +```typescript title="src/lib/prisma.ts" |
| 86 | +import { PrismaClient } from "../generated/prisma/client"; |
| 87 | +import { withAccelerate } from "@prisma/extension-accelerate"; |
| 88 | + |
| 89 | +const prisma = new PrismaClient({ |
| 90 | + datasourceUrl: import.meta.env.DATABASE_URL, |
| 91 | +}).$extends(withAccelerate()); |
| 92 | + |
| 93 | +export default prisma; |
| 94 | +``` |
| 95 | + |
| 96 | +### 查询和显示数据 |
| 97 | + |
| 98 | +以下示例展示了如何使用 Prisma 客户端仅按 `id` 排序获取已发布的帖子,并在 Astro 模板中显示标题和帖子内容: |
| 99 | + |
| 100 | +```astro title="src/pages/posts.astro" {2, 4-7} |
| 101 | +--- |
| 102 | +import prisma from '../lib/prisma'; |
| 103 | +
|
| 104 | +const posts = await prisma.post.findMany({ |
| 105 | + where: { published: true }, |
| 106 | + orderBy: { id: 'desc' } |
| 107 | +}); |
| 108 | +--- |
| 109 | +
|
| 110 | +<html> |
| 111 | + <head> |
| 112 | + <title>Published Posts</title> |
| 113 | + </head> |
| 114 | + <body> |
| 115 | + <h1>Published Posts</h1> |
| 116 | + <ul> |
| 117 | + {posts.map((post) => ( |
| 118 | + <li> |
| 119 | + <h2>{post.title}</h2> |
| 120 | + {post.content && <p>{post.content}</p>} |
| 121 | + </li> |
| 122 | + ))} |
| 123 | + </ul> |
| 124 | + </body> |
| 125 | +</html> |
| 126 | +``` |
| 127 | + |
| 128 | +最好的做法是在 API 路由中处理查询。有关如何在 Astro 项目中使用 Prisma ORM 的更多信息,请参考 [Astro + Prisma ORM 指南](https://www.prisma.io/docs/guides/astro)。 |
| 129 | + |
| 130 | +## 直接 TCP 连接 |
| 131 | +要通过直接 TCP 连接到 Prisma Postgres,你可以在 Prisma 控制台中创建一个直接连接字符串。这样你就能连接任意其他 ORM、数据库库或你选择的工具。 |
| 132 | + |
| 133 | +### 前提条件 |
| 134 | +- 一个已启用 TCP 连接字符串的 [Prisma Postgres](https://pris.ly/ppg) 数据库 |
| 135 | + |
| 136 | +### 安装依赖包 |
| 137 | + |
| 138 | +本示例将使用 [`pg`(一个 Node.js 的 PostgreSQL 客户端)](https://github.com/brianc/node-postgres)来建立直接 TCP 连接。 |
| 139 | + |
| 140 | +运行以下命令来安装 `pg` 包: |
| 141 | + |
| 142 | +```bash |
| 143 | +npm install pg |
| 144 | +``` |
| 145 | + |
| 146 | +### 查询数据库客户端 |
| 147 | + |
| 148 | +将连接字符串提供给 `pg` 客户端,以便与 SQL 服务器通信并从数据库中获取数据。 |
| 149 | + |
| 150 | +以下创建表和插入的数据示例可用于验证你的查询 URL 和 TCP 连接: |
| 151 | + |
| 152 | +```astro title="src/pages/index.astro" {2-19} |
| 153 | +--- |
| 154 | +import { Client } from 'pg'; |
| 155 | +const client = new Client({ |
| 156 | + connectionString: import.meta.env.DATABASE_URL, |
| 157 | + ssl: { rejectUnauthorized: false } |
| 158 | +}); |
| 159 | +await client.connect(); |
| 160 | +
|
| 161 | +await client.query(` |
| 162 | + CREATE TABLE IF NOT EXISTS posts ( |
| 163 | + id SERIAL PRIMARY KEY, |
| 164 | + title TEXT UNIQUE, |
| 165 | + content TEXT |
| 166 | + ); |
| 167 | + |
| 168 | + INSERT INTO posts (title, content) |
| 169 | + VALUES ('Hello', 'World') |
| 170 | + ON CONFLICT (title) DO NOTHING; |
| 171 | +`); |
| 172 | +
|
| 173 | +const { rows } = await client.query('SELECT * FROM posts'); |
| 174 | +await client.end(); |
| 175 | +--- |
| 176 | +
|
| 177 | +<h1>Posts</h1> |
| 178 | +<p>{rows[0].title}: {rows[0].content}</p> |
| 179 | +``` |
| 180 | + |
| 181 | +## 官方资源 |
| 182 | + |
| 183 | +- [Astro + Prisma ORM 指南](https://www.prisma.io/docs/guides/astro) |
0 commit comments