跳至主要内容

查询数据库

使用 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"

帖子

idcreatedAtupdatedAt标题内容已发布authorId
12020-03-21T16:45:01.246Z2020-03-21T16:45:01.246Z"Hello World"nullfalse1

个人资料

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
}

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

帖子

id标题内容已发布authorId
1"Hello World"nulltrue1

太棒了,您刚刚使用 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 入门模板