跳到主要内容

查询数据库

使用 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,
}
}
]

另请注意,由于 Prisma Client 生成的类型allUsers 变量是静态类型的。您可以通过将鼠标悬停在编辑器中的 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]""Alice"

帖子

id创建时间更新时间标题内容已发布作者 ID
12020-03-21T16:45:01.246Z2020-03-21T16:45:01.246Z"Hello World"1

个人资料

id简介用户 ID
1"I like turtles"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
}

id1Post 记录现在已在数据库中更新

帖子

id标题内容已发布作者 ID
1"Hello World"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'
}

当您使用 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'
}

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