跳至主要内容

查询数据库

使用 Prisma Client 编写您的第一个查询

现在您已经生成了 Prisma Client,您可以开始编写查询来读取和写入数据库中的数据。为了本指南的目的,您将使用一个简单的 TypeScript 脚本来探索 Prisma Client 的一些基本功能。

创建一个名为 queries.ts 的新文件,并向其中添加以下代码

queries.ts
// 1
import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

// 2
const prisma = new PrismaClient()
.$extends(withAccelerate())

// 3
async function main() {
// ... you will write your Prisma Client queries here
}

// 4
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
// 5
await prisma.$disconnect()
process.exit(1)
})

以下是代码片段中不同部分的简要概述

  1. 导入 PrismaClient 构造函数和 withAccelerate 扩展。
  2. 实例化 PrismaClient 并添加 Accelerate 扩展。
  3. 定义一个名为 mainasync 函数,用于向数据库发送查询。
  4. 调用 main 函数。
  5. 当脚本终止时关闭数据库连接。

main 函数中,添加以下查询以从数据库中读取所有 User 记录并记录结果

queries.ts
async function main() {
const allUsers = await prisma.user.findMany()
console.log(allUsers)
}

现在使用以下命令运行代码

npx tsx queries.ts

这应该打印一个空数组,因为数据库中还没有 User 记录

[]

将数据写入数据库

您在上一节中使用的 findMany 查询只从数据库中读取数据(尽管它仍然是空的)。

在本节中,您将学习如何编写查询以将新记录写入PostUserProfile 表中,一次全部写入。

通过删除之前代码并添加以下内容来调整 main 函数

queries.ts
async function main() {
await prisma.user.create({
data: {
name: 'Alice',
email: '[email protected]',
posts: {
create: { title: 'Hello World' },
},
profile: {
create: { bio: 'I like turtles' },
},
},
})

const allUsers = await prisma.user.findMany({
include: {
posts: true,
profile: true,
},
})
console.dir(allUsers, { depth: null })
}

此代码使用 嵌套写入 查询创建一个新的 User 记录以及新的 PostProfile 记录。

这些记录通过您在 Prisma 架构中定义的 关系字段 连接。

请注意,您还在传递 include 选项到 findMany,它告诉 Prisma Client 在返回的 User 对象上包含 postsprofile 关系。

使用以下命令运行代码

npx tsx queries.ts

输出应该类似于此

[
{
email: '[email protected]',
id: 1,
name: 'Alice',
posts: [
{
content: null,
createdAt: 2020-03-21T16:45:01.246Z,
updatedAt: 2020-03-21T16:45:01.246Z,
id: 1,
published: false,
title: 'Hello World',
authorId: 1,
}
],
profile: {
bio: 'I like turtles',
id: 1,
userId: 1,
}
}
]

另请注意,allUsers 变量是静态类型的,这得益于 Prisma Client 生成的类型。您可以通过将鼠标悬停在编辑器中的 allUsers 变量上观察类型。它应该被键入如下

const allUsers: ({
posts: {
id: number;
createdAt: Date;
updatedAt: Date;
title: string;
content: string | null;
published: boolean;
authorId: number;
}[];
profile: {
id: number;
bio: string | null;
userId: number;
} | null;
} & {
...;
})[]
展开以查看已创建记录的视觉视图

查询将新记录添加到 UserPostProfile 表中

用户

id电子邮件名称
1"[email protected]""爱丽丝"

帖子

idcreatedAtupdatedAt标题内容已发布authorId
12020-03-21T16:45:01.246Z2020-03-21T16:45:01.246Z"你好世界"1

个人资料

id生物userId
1"我喜欢乌龟"1

Post 上的 authorId 列和 Profile 上的 userId 列中的数字都引用 User 表的 id 列,这意味着 id1 列因此引用数据库中的第一个(也是唯一一个)User 记录。

在继续下一节之前,您将使用 update 查询“发布”刚刚创建的 Post 记录。请按如下方式调整 main 函数

queries.ts
async function main() {
const post = await prisma.post.update({
where: { id: 1 },
data: { published: true },
})
console.log(post)
}

现在使用与之前相同的命令运行代码

npx tsx queries.ts

您将看到以下输出

{
id: 1,
title: 'Hello World',
content: null,
published: true,
authorId: 1
}

Post 记录的 id1 现在已在数据库中更新

帖子

id标题内容已发布authorId
1"你好世界"1

太棒了,您刚刚使用 Prisma Client 🚀 首次将新数据写入数据库。

在数据库中数据发生变化时接收实时更新

由于 Prisma Postgres 默认情况下附带 Prisma Pulse,您只需使用现有的 PrismaClient 实例即可轻松地将数据库中发生的任何更改流式传输到您的应用程序中。让我们看看它是如何工作的!

首先,在您的项目中安装 Pulse Client 扩展

npm install @prisma/extension-pulse

接下来,创建一个名为 realtime.ts 的新文件,并向其中添加以下代码

realtime.ts
// 1
import { PrismaClient } from '@prisma/client';
import { withPulse } from '@prisma/extension-pulse';

// 2
const apiKey: string = process.env.PULSE_API_KEY ?? '';
if (!apiKey || apiKey === "") {
console.log(`Please set the \`PULSE_API_KEY\` environment variable in the \`.env\` file.`);
process.exit(1);
}

// 3
const prisma = new PrismaClient().$extends(
withPulse({ apiKey: apiKey })
);


async function main() {

// 4
const stream = await prisma.user.stream();

process.on('exit', () => {
stream.stop();
});

// 5
console.log(`Waiting for an event on the \`User\` table ... `);
for await (const event of stream) {
console.log('Received an event:', event);
}
}

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

这里发生了一些事情,让我们仔细看看

  1. 导入 PrismaClient 构造函数和 withPulse 扩展。
  2. 读取 PULSE_API_KEY 环境变量(它在 .env 文件中配置)。
  3. 实例化 PrismaClient 并添加 Pulse 扩展(使用 Pulse API 密钥)。
  4. 创建一个来捕获 User 表上的任何 写入事件
  5. 启动一个异步迭代器,该迭代器等待新的事件并将它们记录到您的终端。

使用以下命令启动脚本

npx tsx realtime.ts

您应该看到以下输出

Waiting for an event on the `User` table ... 

在同一个终端中,您现在将看到每当以下情况发生时,都会记录新的输出

  • 创建新的 User 记录
  • 更新现有的 User 记录
  • 删除现有的 User 记录

要触发其中一个事件,您可以使用 Prisma Studio。继续并使用以下命令打开它(在一个新的终端选项卡或窗口中)

npx prisma studio

如果您在视觉编辑器中创建了一个新的 User 记录,您应该在之前的终端选项卡/窗口中看到类似于此的输出

Received an event: {
action: 'create',
created: { id: @, email: '[email protected]', name: 'Bob' },
id: '01JAFNSZHQRDTW773BCAA9G7FJ',
modelName: 'User'
}

当您使用 Prisma Client 写入数据库时,也会触发这些更改事件。例如,您可以使用以下 update 查询更新 queries.ts 文件,将用户从 "Alice" 重命名为 "Alicia"

queries.ts
async function main() {
await prisma.user.update({
where: {
id: 1
},
data: {
name: 'Alicia',
email: '[email protected]',
}
});
}

然后,您可以使用之前的命令(在一个新的终端选项卡或窗口中)运行脚本

npx tsx queries.ts

您现在应该在之前的终端选项卡/窗口中看到类似于此的输出

{
action: 'update',
after: { id: 1, email: '[email protected]', name: 'Alicia' },
before: null,
id: '0/2A5A248',
modelName: 'User'
}

恭喜!您现在已经了解了如何使用 Prisma Client 查询 Prisma Postgres 数据库以及如何在您的应用程序中接收实时事件。如果您在中途迷路了,想要了解有关更多查询的信息或探索 Prisma Accelerate 的缓存功能,请查看全面的 Prisma 入门模板