入门:在 TodoApp 中定义数据模型并生成迁移)
Wasp 数据库实体Entity入门在 TodoApp 中定义数据模型并生成迁移【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/waspEntity实体是 Wasp 框架中最核心的概念之一它决定了应用在数据库中究竟存储什么、以什么结构存储。本篇指南以 Wasp 0.11.8 官方 Todo 教程第 4 步为骨架讲解如何用 Prisma Schema LanguagePSL在main.wasp中定义Task实体、用wasp db migrate-dev同步数据库结构以及用wasp db studio可视化查看与编辑数据同时结合当前仓库中的 TodoApp 示例与源码补充实体在 Operations 中的实际调用方式和架构演进。读完你将掌握 Wasp 项目中最基本的定义数据模型 → 生成迁移 → 查看数据完整工作流。什么是 Wasp Entity在 Wasp 中Entity 是应用数据模型的基石——简单来说一个 Entity 就是在数据库中定义一个模型表。Todo 应用的全部业务都围绕任务展开因此教程的第一步就是在 Wasp 文件中定义一个Task实体。Wasp 底层使用 Prisma ORM。在 main.wasp 中定义 Task 实体在main.wasp文件中加入下面的声明// ... entity Task {psl id Int id default(autoincrement()) description String isDone Boolean default(false) psl}逐行拆解这段声明entity Task告诉 Wasp 定义一个名为Task的实体即数据库模型。Wasp 会自动生成名为tasks的表。{psl ... psl}Wasp 将这对标签之间的内容视为 PSL 代码交给 Prisma 解析。id Int id default(autoincrement())整数类型的主键数据库会自动为每条新记录生成自增的id。description String字符串字段用于存储任务描述。isDone Boolean default(false)布尔字段表示任务完成状态创建任务时不显式赋值数据库会默认写入false。也就是说上述 PSL 会让 Wasp 创建一张包含三列的tasks表主键id、描述description、完成标记isDone。仓库中的 TodoApp 示例examples/tutorials/TodoApp/schema.prisma展示了同样的数据模型model Task { id Int id default(autoincrement()) description String isDone Boolean default(false) user User? relation(fields: [userId], references: [id]) userId Int? }从源码可以看出当前版本的示例还额外为Task关联了User外键userId与user关系字段这正是教程后续接入登录鉴权后需要用到的结构。这印证了 0.11.8 教程中实体定义会随着需求不断演进的说法——先定义最小的模型再通过迁移逐步扩展。同步数据库wasp db migrate-dev定义好实体后数据库的 schema 还停留在旧状态。如果wasp start正在运行先停止它然后执行wasp db migrate-dev这条命令做的事是对比main.wasp中的实体定义与当前数据库结构由 Prisma 生成一份新的迁移脚本并应用到数据库。每当你修改任何一个实体的定义新增字段、修改类型、删除字段、增加关联等都需要重新执行它。生成的迁移脚本会自动放在项目的migrations/文件夹中。这个文件夹应提交到版本控制commit因为它是数据库结构的权威历史记录团队其他成员和部署环境都需要依靠它重建一致的 schema。仓库中 TodoApp 的迁移目录examples/tutorials/TodoApp/migrations/保存了完整的演进历史其中初始迁移20240716202057_initial/migration.sql生成的 SQL 与我们定义的Task实体一一对应-- CreateTable CREATE TABLE Task ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, description TEXT NOT NULL, isDone BOOLEAN NOT NULL DEFAULT false );可以看到Int id default(autoincrement())变成了INTEGER NOT NULL PRIMARY KEY AUTOINCREMENTdescription String变成TEXT NOT NULLisDone Boolean default(false)变成BOOLEAN NOT NULL DEFAULT false。这直观展示了 PSL 声明如何被翻译成真实的 SQL DDL——理解这一点有助于你判断字段约束、默认值和索引的实际落地效果。查看数据wasp db studio数据库 schema 更新后如何确认Task实体长什么样运行wasp db studio该命令会在浏览器中打开一个可视化数据库管理页面Prisma Studio让你查看并直接编辑数据库中的数据。在上面的截图中Prisma Studio 的模型选择界面列出了Task模型右侧数字0表示当前数据库中Task表还没有任何记录——因为迁移只创建了表结构数据要等我们通过 Queries/Actions 写入。点击Task即可进入它的字段列表与数据浏览界面检查各列的属性是否符合预期。在 Operations 中使用实体定义实体只是第一步真正高频的使用场景是在OperationsQueries 与 Actions中读写实体。0.11.8 的 Entities 文档 给出的标准工作流是在main.wasp或schema.prisma中创建/更新实体运行wasp db migrate-dev同步数据库并生成迁移脚本将migrations/文件夹提交到版本控制在实现 Operations 时通过 Wasp 的 JavaScript API 访问数据库。以当前仓库的 TodoAppTs 示例examples/tutorials/TodoAppTs/src/queries.ts为例Queries 通过context.entities.Task直接访问实体import type { Task } from wasp/entities; import { HttpError } from wasp/server; import type { GetTasks } from wasp/server/operations; export const getTasks: GetTasksvoid, Task[] async (args, context) { if (!context.user) { throw new HttpError(401); } return context.entities.Task.findMany({ where: { user: { id: context.user.id } }, orderBy: { id: asc }, }); };这里有三点值得注意context.entities.Task是 Wasp 根据实体自动注入的访问入口findMany等 API 即来自 Prisma ClientQuery 的返回类型直接用Task[]从wasp/entities导入实体结构一旦变更类型错误会立即提醒你同步更新调用方代码实现端到端类型安全要让某个 Operation 能访问实体还需要在main.wasp.ts中显式声明依赖。TodoApp 的 main.wasp.ts 中可以看到query(getTasks, { entities: [Task] }), action(createTask, { entities: [Task] }), action(updateTask, { entities: [Task] }),entities: [Task]声明了getTasks、createTask、updateTask这三个操作各自需要访问Task实体Wasp 会据此注入对应的 Prisma 访问权限与类型。进阶直接使用 Prisma Client如果 Wasp 提供的机制不够用你也可以在服务端代码中直接导入并操作 Prisma Client获得更底层的控制力。在 0.11.8 版本中的导入方式为import prismaClient from wasp/dbClient prismaClient.task.create({ description: Read the Entities doc, isDone: true // almost :) })需要强调的是Prisma Client 只能用在 Wasp 的服务端代码中不能在前端client代码里直接执行数据库操作。官方建议优先使用 Wasp 封装好的机制如 Operations 与context.entities仅在确实需要 Prisma 独有能力时才绕过封装。从 0.11.8 到当前仓库实体的两种定义形态细心的读者会发现教程写的是在main.wasp中用{psl psl}定义实体而当前仓库的 TodoApp 示例却把模型放在独立的schema.prisma文件里。这是 Wasp 演进过程中的一个重要变化0.11.8 时代实体内嵌在main.wasp文件的entity声明中Prisma Client 通过wasp/dbClient导入当前仓库新版使用独立的schema.prisma文件定义数据模型Wasp 会自动读取其中所有 Prisma model 作为实体类型通过wasp/entities、wasp/server等虚拟模块导入代码风格也全面 TypeScript 化main.wasp.ts。两个版本的核心思想完全一致PSL 定义模型、wasp db migrate-dev生成迁移、migrations/目录保存历史、Operations 通过注入的实体访问入口读写数据。无论你使用哪种形态的项目这套数据模型工作流都是相通的。关于 Prisma Schema 文件的详细说明如enum块、关系定义等可参考当前仓库的 prisma-file 文档 对应章节以及示例项目中的schema.prisma完整内容。小结本篇围绕 Todo 教程第 4 步完整覆盖了 Wasp 实体从定义到落库再到查看的闭环环节操作作用定义模型在main.wasp中用{psl psl}写entity Task声明Task表及id/description/isDone三列同步数据库wasp db migrate-dev由 Prisma 生成迁移脚本并应用到数据库保存历史提交migrations/文件夹记录 schema 演进供团队与部署复用查看数据wasp db studio在浏览器中可视化查看/编辑表结构与数据读写数据Operations 中通过context.entities.Task访问在 Queries/Actions 中安全地操作实体接下来教程将进入 Queries查询环节届时你会看到实体如何与 Operations 深度配合构建出真正可用的数据读写链路——那也是理解 Wasp 全栈能力的关键一步。【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考