
Wasp 数据库后端实战指南SQLite / PostgreSQL 的连接、迁移与数据播种【免费下载链接】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本篇指南以 Waspv0.14 时代文档体系的数据层为背景系统讲解 Wasp 项目如何选择数据库后端、如何连接开发数据库、如何从 SQLite 平滑迁移到 PostgreSQL以及如何使用app.db.seeds编写并执行数据库播种seeding函数。读完本文你将掌握 Wasp 中数据库配置的完整链路——从schema.prisma的provider切换、DATABASE_URL环境变量的注入方式到wasp db系列命令的实际用法并理解其底层AppSpec Db 定义 与 Seed 生成器是如何工作的。数据库在 Wasp 数据层中的位置在 Wasp 中Entities、Operations 与 Automatic CRUD 共同构成了操作应用数据的高层接口Entities 定义数据模型Operations 声明查询与操作Automatic CRUD 则自动生成常见的增删改查接口。但无论接口多高数据最终都要落到某个存储介质上——这就是数据库后端要解决的问题。Wasp 把数据库抽象为两部分schema.prisma文件遵循 Prisma 的 datasource 语法声明数据库provider和连接urlapp.db配置写在main.wasp中声明播种函数等数据库相关能力。两条线索最终都会在编译阶段被 Wasp 读取并生成对应的服务端代码因此理解二者的关系是掌握 Wasp 数据库用法的前提。支持的数据库后端Wasp 在 AppSpec 的 Db 模块中把数据库系统建模为枚举DbSystem PostgreSQL | SQLite即官方支持且经过代码路径校验的后端只有两个SQLite 与 PostgreSQL。下面分别说明。SQLite默认的开发数据库当你通过wasp new创建新项目时生成器会写出以 SQLite 为默认 provider 的schema.prisma见 basic 模板 与 minimal 模板datasource db { provider sqlite url env(DATABASE_URL) } // ...使用 SQLite 时Wasp 会自动为你设置DATABASE_URL环境变量你不需要准备任何数据库服务、不需要 Docker、不需要安装额外的中间件。这正是它适合快速起步的原因。但需要注意它的边界SQLite 只能用于开发阶段。一旦你要把 Wasp 应用部署到生产环境就必须切换到 PostgreSQL并且之后保持使用 PostgreSQLWasp 不会在生产环境替你管理 SQLite。好在迁移过程并不复杂本文后续有专门的迁移章节指导你完成切换。PostgreSQL面向生产的选择PostgreSQL 是一款在开源数据库领域久经考验的成熟产品适合对稳定性、并发和特性有更高要求的应用。在 Wasp 中使用 PostgreSQL 同样简单只需把schema.prisma中的 provider 改为postgresqldatasource db { provider postgresql url env(DATABASE_URL) } // ...一旦切换到 PostgreSQL你必须在开发期间保证有一个数据库实例在运行——Wasp 执行wasp start或wasp db migrate-dev等命令时都需要真实可用的数据库连接。至于如何提供这个连接请看下一节。仓库中的示例项目可以印证这一点例如 ask-the-documents 的 schema.prisma 就是一个真实使用 PostgreSQL 的案例它还额外启用了pgvector扩展来存储向量字段这说明schema.prisma中 Prisma 支持的能力扩展、生成器等在 Wasp 中都可以正常使用。连接数据库使用 SQLite零配置如果你使用 SQLite连接工作完全由 Wasp 接管无需任何额外操作。DATABASE_URL由 Wasp 在启动时注入你只需要正常执行wasp start即可。使用 PostgreSQL两种连接方式使用 PostgreSQL 时Wasp 提供两种连接策略托管式体验让 Wasp 帮你启动一个开箱即用的开发数据库自主控制你自己准备数据库通过DATABASE_URL连接串告诉 Wasp。方式一使用 Wasp 提供的开发数据库执行下面的命令Wasp 会为你启动一个默认的 PostgreSQL 开发数据库wasp start dbWasp 应用会自动连接上它只需让wasp start db在后台保持运行。使用前请确认本机已安装 Docker 且docker命令在PATH中可用wasp start db正是通过 Docker 拉起 PostgreSQL 容器端口5432没有被其他进程占用。提示如果你希望通过psql、pgAdmin 等外部工具连接这个开发数据库运行wasp db start时控制台最开头打印的就是它的连接凭据。方式二连接已有的数据库如果你想自建开发数据库或连接外部如远端数据库通过DATABASE_URL环境变量告知 Wasp 即可Wasp 会把它当作连接串直接使用。最简单的做法是把DATABASE_URL写进项目根目录的 .env.server 文件该文件不存在则新建DATABASE_URLpostgresql://user:passwordlocalhost:5432/mydb也可以在执行wasp命令时以内联方式注入对所有环境变量均适用DATABASE_URLmy-db-url wasp ...这个技巧非常适合针对特定数据库执行某条命令。例如对全新的 staging 或 production 数据库做初始化播种DATABASE_URLproduction-db-url wasp db seed myProductionSeed上述命令会把种子数据写入目标生产/预发布数据库——这正是「播种」最常见的生产场景之一更多细节见播种数据库一节。从 SQLite 迁移到 PostgreSQL要把应用带上生产环境你需要完成 SQLite → PostgreSQL 的切换。Wasp 给出的迁移步骤很直接第 1 步切换 provider把schema.prisma中的 provider 改为postgresqldatasource db { provider postgresql url env(DATABASE_URL) } // ...第 2 步清掉旧的迁移与旧数据库旧迁移文件是面向 SQLite 生成的无法用于 PostgreSQLSQLite 数据库文件本身也不再需要。删除迁移目录后用wasp clean清理生成产物rm -r migrations/ wasp clean第 3 步确保新数据库在运行参考连接数据库一节启动 PostgreSQL可以用wasp start db也可以自己准备并设置好DATABASE_URL。让它在后台保持运行因为下一步需要它。第 4 步生成初始迁移在另一个终端中执行wasp db migrate-devWasp 会连接你正在运行的 PostgreSQL把当前 schema 应用到数据库并生成一份全新的初始迁移。第 5 步完成至此迁移结束。此后项目将一直以 PostgreSQL 为数据库后端schema.prisma的新改动继续通过wasp db migrate-dev管理。播种数据库**数据库播种database seeding**指的是向数据库填充初始数据的过程。最常见的两种用途把开发数据库置入一个方便开发与测试的状态为任意环境dev / staging / prod的数据库初始化其运转所必需的基准数据例如向 Currency 表填充默认币种、向 Country 表填充全部国家。编写 Seed 函数在main.wasp中你可以在app.db.seeds字段下以数组形式声明任意多个seed 函数app MyApp { // ... db: { seeds: [ import { devSeedSimple } from src/dbSeeds.js, import { prodSeed } from src/dbSeeds.js ] } }如果你使用的是新版 TypeScript 规范main.wasp.ts同样的声明方式见 kitchen-sink 示例中的 db 配置它同时展示了seeds与prismaSetupFn两个字段的写法。每个 seed 函数必须是接收一个参数的 async 函数该参数prisma是用于操作数据库的 Prisma Client 实例——这个实例与 Wasp 内部使用的完全一致。由于 seed 函数属于服务端代码它天然可以导入其他服务端函数。这意味着你可以很方便地「用 Action 来播种」——例如下面的例子seed 函数同时创建了一个带用户名密码的用户并调用createTask这个 Action 为用户创建任务import { createTask } from ./actions.js import { sanitizeAndSerializeProviderData } from wasp/server/auth export const devSeedSimple async (prisma) { const user await createUser(prisma, { username: RiuTheDog, password: bark1234, }) await createTask( { description: Chase the cat }, { user, entities: { Task: prisma.task } } ) } async function createUser(prisma, data) { const newUser await prisma.user.create({ data: { auth: { create: { identities: { create: { providerName: username, providerUserId: data.username, providerData: sanitizeAndSerializeProviderData({ hashedPassword: data.password }), }, }, }, }, }, }) return newUser }代码中有两点值得注意创建用户时直接操作prisma.user并在auth.identities中写入providerName: username的身份数据hashedPassword经过sanitizeAndSerializeProviderData序列化——这与 Wasp 内部创建用户名密码登录身份的实现一致createTask的第二个参数携带{ user, entities: { Task: prisma.task } }这是 Wasp Action 执行上下文context的标准形态说明 seed 完全可以复用应用中已有的操作逻辑。TypeScript 版本使用DbSeedFn类型标注 seed 函数import { createTask } from ./actions.js import { type DbSeedFn } from wasp/server import { sanitizeAndSerializeProviderData } from wasp/server/auth import { type AuthUser } from wasp/auth import { PrismaClient } from prisma/client export const devSeedSimple: DbSeedFn async (prisma) { const user await createUser(prisma, { username: RiuTheDog, password: bark1234, }) await createTask( { description: Chase the cat, isDone: false }, { user, entities: { Task: prisma.task } } ) }; async function createUser( prisma: PrismaClient, data: { username: string, password: string } ): PromiseAuthUser { const newUser await prisma.user.create({ data: { auth: { create: { identities: { create: { providerName: username, providerUserId: data.username, providerData: sanitizeAndSerializeProviderDatausername({ hashedPassword: data.password }), }, }, }, }, }, }) return newUser }DbSeedFn由 Wasp 导出其定义如下type DbSeedFn (prisma: PrismaClient) Promisevoid给devSeedSimple标注该类型后TypeScript 会得到两重保证seed 函数的参数prisma类型为PrismaClientseed 函数的返回值类型为Promisevoid。仓库中的真实范例可以参考 kitchen-sink 的 seeds.ts它同时导出了devSeedSimple与prodSeed两个 seed 函数分别向开发库与生产库写入用户名、任务等初始数据并打印日志确认执行结果——与本文示例模式完全一致。运行 Seed 函数运行命令wasp db seed如果你定义了多个 seed 函数Wasp 会以交互方式让你选择运行哪一个只定义了一个则会直接运行。也可以直接指定名称执行wasp db seed devSeedSimple实用技巧在wasp db reset清空数据库之后紧接着运行wasp db seed把初始数据填回去是开发中最常见的组合操作。API 参考app.db 与种子命令app.db 配置项app.db是一个字典所有字段均为可选app MyApp { title: My app, // ... db: { seeds: [ import devSeed from src/dbSeeds.js ], } }seeds: [ExtImport]定义可用wasp db seed命令执行的 seed 函数列表用于向数据库填充初始数据。每个元素是一个外部导入ExtImport指向src/下的服务端模块。完整的语义见播种数据库一节。从源码实现看AppSpec 的 Db 记录除了seeds外还定义了prismaSetupFn字段——后者用于注入自定义的 Prisma 初始化逻辑如示例中的setUpPrisma说明app.db在设计上就是围绕 Prisma 生态的可扩展配置入口。CLI 命令wasp db seed只定义一个 seed 函数时直接运行它定义多个时以交互方式让你选择。wasp db seed seed-name直接运行指定名称的 seed 函数。该名称就是它在app.db.seeds列表的import表达式中的标识符。例如对如下声明app MyApp { // ... db: { seeds: [ // ... import { devSeedSimple } from src/dbSeeds.js, ] } }运行wasp db seed devSeedSimple源码视角db 命令与种子生成的底层机制理解 Wasp 是如何执行这些命令的有助于排查问题。db 命令的公共前置流程。在 CLI 的 Db 模块中所有wasp db ...命令都经由makeDbCommand包装它依次完成校验当前目录是 Wasp 项目InWaspProject校验 Wasp 规范文件可用WaspSpecAvailable执行编译并安装 npm 依赖compileWithOptions即代码生成阶段校验数据库连接已建立DbConnectionEstablished。这正是文档中「Wasp 需要访问你的数据库才能执行wasp start、wasp db migrate-dev」这一说法的代码依据——任何 db 命令的前提都是「先编译出代码、再连上数据库」。种子脚本的生成。在代码生成阶段Seed 生成器读取 AppSpec 中的seeds列表为服务端生成dbSeed.ts脚本并把每个 ExtImport 转换为可注入的导入当存在至少一个 seed 时它还会在package.json的 Prisma 配置中注册prisma.seed npm run db-seedgetPackageJsonPrismaSeedField从而让 Prisma 层面的 seed 机制与 Wasp 的 seed 命令打通。此外它还定义了环境变量名WASP_DB_SEED_NAME见 Seed.hs——wasp db seed name正是通过向该环境变量写入指定名称再由生成的脚本据此挑选并执行对应的 seed 函数。小结围绕 Wasp 的数据库能力你需要记住四条主线默认 SQLite、生产 PostgreSQL新项目开箱即用 SQLite零配置、仅限开发上线前务必切换到 PostgreSQL连接方式二选一wasp start db走 Docker 拉起托管开发库或通过.env.server/ 命令行内联注入DATABASE_URL连接自建库迁移三步走改 provider →rm -r migrations/wasp clean→ 确保 PG 运行后wasp db migrate-dev播种即服务端函数在app.db.seeds中声明任意多个(prisma) Promisevoid函数推荐用DbSeedFn标注类型用wasp db seed [name]执行可用于初始化 dev / staging / prod 任意环境的基准数据。把上述操作与 AppSpec Db 定义、Seed 生成器 及 kitchen-sink 示例 对照阅读你就能在 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),仅供参考