ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Wasp 数据模型基石:深入理解 schema.prisma 与 Prisma 集成

Wasp 数据模型基石:深入理解 schema.prisma 与 Prisma 集成 Wasp 数据模型基石深入理解 schema.prisma 与 Prisma 集成【免费下载链接】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/waspschema.prisma是 Wasp 项目中定义数据库数据模型的唯一入口。Wasp 基于 Prisma ORM 构建数据层本文将以 Wasp 0.14 的官方文档为主线系统讲解schema.prisma在项目中的位置、datasource/generator/model三大配置块的作用、Wasp 特有的配置约束以及 Prisma 预览特性如 PostgreSQL 扩展的启用方式并结合仓库内的真实示例与编译器源码帮助你真正理解数据模型从定义到生成 Entity 的全链路原理。Wasp 与 Prisma为什么需要 schema.prismaWasp 使用 Prisma 与数据库交互。Prisma 被称为下一代 Node.js 和 TypeScript ORM它提供了一套类型安全的 API 来操作数据库。在 Wasp 项目中你的数据模型并不直接写在main.wasp中而是统一以 Prisma Schema LanguagePSL定义在项目根目录的schema.prisma文件里。Wasp 读取该文件理解应用的数据模型与数据库配置并据此生成与数据库交互所需的代码。也就是说schema.prisma是 Wasp 数据层的单一事实来源你在这里定义模型Wasp 负责把它们转换成可在代码中使用的 Wasp Entity并完成 Prisma Client 的生成与迁移工作。在 Wasp 0.14 的项目中文件结构如下. ├── main.wasp ... ├── schema.prisma ├── src ├── tsconfig.json └── vite.config.tsWasp 文件与 Prisma schema 文件的协同工作要理解 Wasp 的数据层关键是先看清main.wasp与schema.prisma如何各司其职。以下是一个完整的schema.prisma示例它定义了一个datasource数据源、一个generator生成器以及两个具有一对多关系的模型User和Taskdatasource db { provider postgresql url env(DATABASE_URL) } generator client { provider prisma-client-js } model User { id Int id default(autoincrement()) tasks Task[] } model Task { id Int id default(autoincrement()) description String isDone Boolean default(false) user User relation(fields: [userId], references: [id]) userId Int }这个文件由三个核心部分组成datasource块定义要使用的数据库类型此处为 PostgreSQL以及其他数据库相关选项generator块定义如何生成 Prisma Client 代码供应用在运行时操作数据库model块声明具体的数据模型及其字段、类型、默认值与关系。下图直观展示了schema.prisma与main.wasp之间的关系Prisma 的models会被引入 Wasp 成为entities而这些 Entity 随后被operations查询/操作、apis等 Wasp 功能引用Prisma 模型成为 Wasp Entity 后的使用方式Prisma 模型最终会成为 Wasp Entity并可直接在main.wasp中使用。下面是在 Wasp 0.14 的main.wasp中引用 Entity 的完整示例app myApp { wasp: { version: ^0.14.0 }, title: My App, } ... // Using Wasp Entities in the Wasp file query getTasks { fn: import { getTasks } from src/queries, entities: [Task] } job myJob { executor: PgBoss, perform: { fn: import { foo } from src/workers/bar }, entities: [Task], } api fooBar { fn: import { fooBar } from src/apis, entities: [Task], httpRoute: (GET, /foo/bar/:email) }在getTasks查询的实现中Task就是与schema.prisma中Task模型相对应的 Wasp Entity。myJob后台任务和fooBarAPI 同样通过entities字段声明了对Task的访问权限。声明了entities后Wasp 会在这些功能的上下文context.entities中注入对应模型的 Prisma Client供你的实现代码直接调用。Wasp Entity 与 Prisma 模型之间的完整映射关系可进一步参阅 Entities 页面。Wasp 特定的 Prisma 配置规则Wasp 允许你像在任何普通 JS/TS 项目中一样使用schema.prisma但为了保证框架能正确处理数据库与生成代码它对配置块施加了几条必须遵守的规则。datasource 块datasource db { provider postgresql url env(DATABASE_URL) }Wasp 会原样采用你写的datasource配置但有两条硬性规则provider只能是postgresql或sqlite目前 Wasp 仅支持 PostgreSQL 和 SQLite 两类数据库。在仓库中这一约束也有迹可循——waspc/src/Wasp/Psl模块中保存了dbProviderPostgresqlStringLiteral等数据库 provider 的字面量定义。url字段必须设置为env(DATABASE_URL)Wasp 依赖DATABASE_URL环境变量来连接数据库因此该字段不能硬编码为其他值。generator 块generator client { provider prisma-client-js }Wasp 要求schema.prisma中必须存在一个provider prisma-client-js的 generator 块它是 Wasp 生成类型安全客户端代码的基础。同时Wasp 也允许你按需添加额外的 generator例如用于生成文档或自定义客户端代码的 generator。model 块model User { id Int id default(autoincrement()) tasks Task[] } model Task { id Int id default(autoincrement()) description String isDone Boolean default(false) user User relation(fields: [userId], references: [id]) userId Int }对于model块Wasp 不做额外限制只要是合法的 Prisma schema 代码就能在 Wasp 中正常工作。这意味着 Prisma 的全部类型系统、字段修饰符id、default、unique、updatedAt等与关系语法relation、标量列表字段都可以直接使用。三斜杠注释的限制:::note 三斜杠注释 在 Wasp 0.14 中/// comment语法尚未被完全支持。目前该能力仍在社区中跟踪推进若你的项目确实需要此功能可以关注上游 issue 的动态。 :::这意味着在定义字段时暂时避免依赖///开头的文档注释来承载关键信息改用常规的//注释或直接通过字段命名表达语义是更稳妥的做法。从仓库示例看真实世界的 schema.prisma仓库中的多个示例应用可以作为最佳实践参考展示schema.prisma在真实项目中的形态。kitchen-sink 示例 展示了包含枚举、多模型关系与多字段索引的完整数据模型。它在一处同时演示了枚举、一对多关系与多对多关系datasource db { provider postgresql // Wasp requires that the url is set to the DATABASE_URL environment variable. url env(DATABASE_URL) } // Wasp requires the prisma-client-js generator to be present. generator client { provider prisma-client-js } enum TaskVisibility { PRIVATE LINK_ONLY PUBLIC } model Task { id Int id default(autoincrement()) description String isDone Boolean default(false) user User relation(fields: [userId], references: [id]) userId Int votes TaskVote[] visibility TaskVisibility default(PRIVATE) }这里TaskVisibility枚举被用作Task.visibility字段的类型默认值为PRIVATE。注意该文件中的注释恰好对应了上文的两条 Wasp 规则——url必须是env(DATABASE_URL)且必须存在prisma-client-jsgenerator。waspello 示例 则演示了典型的一对多关系建模一个List属于一个User一个Card同时属于一个List与一个Usermodel List { id Int id default(autoincrement()) name String pos Float // List has a single author. user User relation(fields: [userId], references: [id]) userId Int cards Card[] }可以看到Wasp 项目中的schema.prisma与标准 Prisma 项目没有差别关系的双向字段标量外键userId与关系字段user需要成对声明这是 Prisma 本身的语法要求。Prisma 预览特性以 PostgreSQL 扩展为例Prisma 仍处于活跃开发阶段部分功能尚未进入稳定版本。要启用这些预览特性需要在generator块中添加previewFeatures字段。一个非常实用的预览特性是PostgreSQL 扩展支持postgresqlExtensions它允许你在数据库 schema 中使用pgvector、pg_trgm等 PostgreSQL 扩展。启用方式如下datasource db { provider postgresql url env(DATABASE_URL) extensions [pgvector(map: vector)] } generator client { provider prisma-client-js previewFeatures [postgresqlExtensions] } // ...在datasource块的extensions数组中声明所需扩展后就可以在模型字段中直接使用该扩展提供的类型了。仓库中的 ask-the-documents 示例 就是这一特性的真实落地它启用pgvector扩展并在Document模型中使用Unsupported(vector(1536))字段类型来存储文档的向量嵌入用于语义检索datasource db { provider postgresql url env(DATABASE_URL) extensions [pgvector(map: vector)] } generator client { provider prisma-client-js previewFeatures [postgresqlExtensions] } model Document { id String id default(uuid()) title String url String unique content String embedding Unsupported(vector(1536)) createdAt DateTime default(now()) updatedAt DateTime updatedAt }其他预览特性的启用方式与此一致将特性名加入previewFeatures列表即可。需要说明的是预览特性的可用性取决于 Prisma 客户端版本具体支持范围请以项目实际锁定的 Prisma 版本为准。源码视角Wasp 编译器如何解析 schema.prisma理解schema.prisma的配置规则不妨再看一眼 Wasp 编译器底层是如何解析该文件的。在 Wasp 编译器的 PSL 解析模块中datasource与generator被统一建模为配置块。waspc/src/Wasp/Psl/Ast/ConfigBlock.hs中的ConfigBlock数据结构定义了ConfigBlockType仅有Datasource和Generator两种与键值对列表-- | Represents a config block in the PSL. -- For example, in the following PSL: -- -- generator client { -- provider prisma-client-js -- } -- -- The config block would be ConfigBlock Generator client [KeyValuePair provider \prisma-client-js\]. data ConfigBlock ConfigBlock { _type :: ConfigBlockType, _name :: Name, _keyValuePairs :: [KeyValuePair] }这段源码印证了前文的规则Wasp 的 PSL 解析器能够识别datasource与generator两类配置块并从键值对中读取provider、url、extensions、previewFeatures等字段。与此同时model块则走另一条独立的 AST 路径被解析为 Entity 声明——Wasp 编译器在解析完schema.prisma后会把其中的模型注入到 AppSpec应用规范中供后续生成器使用这也解释了模型自动成为 Entity的行为。从生成器侧看DbGenerator 模块 会比对用户schema.prisma与上次数据库同步时记录的校验和当检测到schema.prisma发生变化且与数据库不一致时会提示你运行wasp db migrate-dev生成迁移脚本。这也是 Wasp 常规工作流的一部分修改schema.prisma→ 运行wasp db migrate-dev→ 迁移脚本自动落入migrations/目录该目录应提交到版本控制→ 在 Operations 中通过context.entities使用 Entity。另外值得一提的是AppSpec 校验逻辑 中还包含一条与数据库 provider 相关的约束如果应用中的 job 使用了PgBoss执行器则schema.prisma中的 provider 必须是 PostgreSQL因为 PgBoss 依赖 PostgreSQL 的消息队列能力。这属于 provider 选择对上层功能的连带约束值得在选择数据库时一并考虑。总结schema.prisma是 Wasp 数据层的核心配置文件它既保留了对标准 Prisma 语法的完整兼容又附加了少量 Wasp 特有的约束provider限定为 PostgreSQL/SQLite、url固定为env(DATABASE_URL)、必须存在prisma-client-jsgenerator。在此之上你可以自由定义模型、枚举与关系并通过previewFeatures启用postgresqlExtensions等预览能力为向量检索等高级场景提供支撑。理解这些规则你就能在 Wasp 项目中游刃有余地设计数据模型并借助 Prisma 的类型安全与迁移能力快速迭代应用。【免费下载链接】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),仅供参考
返回列表