ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Wasp 数据库完全指南:SQLite 与 PostgreSQL 的连接、迁移与数据播种

2026/9/15 22:19:17 拓冰建站 浏览量
Wasp 数据库完全指南:SQLite 与 PostgreSQL 的连接、迁移与数据播种 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/waspoutput_articleWasp 数据库完全指南SQLite 与 PostgreSQL 的连接、迁移与数据播种本篇指南基于 Wasp 0.18 版本文档整理系统讲解 Wasp 框架的数据库体系支持的数据库后端、两种连接 PostgreSQL 的方式、从 SQLite 平滑迁移到 PostgreSQL 的完整步骤以及如何通过 seed 函数为数据库填充初始数据、如何自定义 Prisma Client。读完本文你将掌握 Wasp 项目数据库从开发到生产落地的全流程实操方案。在 Wasp 中Entities、Operations 和 Automatic CRUD 共同构成了操作应用数据的高级接口但所有数据终究要落到某个存储中。Wasp 通过 Prisma 与数据库交互——你可以在项目根目录的schema.prisma文件中定义数据模型与数据库配置详见 Prisma schema file由 Wasp 读取并生成访问数据库所需的全部代码。支持的数据库后端Wasp 目前支持两种数据库后端SQLite 与 PostgreSQL。从源码来看Prisma 的datasource块的provider字段只能取postgresql或sqlite因为 Wasp 目前只支持这两种数据库见 prisma-file.md。SQLite开箱即用的默认选择新建 Wasp 项目时schema.prisma文件会默认将 SQLite 设为数据库提供方。仓库中的示例项目就是最直接的证据例如 examples/tutorials/TodoApp/schema.prismadatasource db { provider sqlite // 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 } 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? }使用 SQLite 时Wasp 会替你设置DATABASE_URL环境变量你无需任何额外配置即可连接数据库。这在 wasp-app-runner/src/db/sqlite.ts 中体现得很直观export const setupSqlite async (): PromiseSetupDbResult { // No need to do anything special for SQLite, just return // an empty object for the env vars. return { dbEnvVars: {}, }; };SQLite 非常适合新项目起步因为它零配置。但请注意SQLite 只能用于开发环境。一旦你要把 Wasp 应用部署到生产环境就必须切换到 PostgreSQL。好消息是迁移过程相当简单下文有专门的迁移指南。PostgreSQL生产环境的战斗之选PostgreSQL 是当前最先进的开源数据库之一也是整体上最流行的数据库之一已持续活跃开发 20 多年。如果你在寻找久经考验的数据库它就是不二之选。要使用 PostgreSQL只需把schema.prisma中的provider改为postgresqldatasource db { provider postgresql url env(DATABASE_URL) } // ...注意开发期间你必须确保有一个正在运行的数据库实例——wasp start、wasp db migrate-dev等命令都需要访问你的数据库。如何连接数据库见下一节。仓库中的多数示例项目都采用 PostgreSQL例如 examples/ask-the-documents/schema.prisma、examples/waspello/schema.prisma 和 examples/kitchen-sink/schema.prisma。连接数据库的两种方式SQLite无需任何操作如果使用 SQLite你不需要做任何特殊处理来连接数据库Wasp 会替你完成一切。PostgreSQL托管开发库或自建库二选一如果使用 PostgreSQLWasp 支持两种连接方式托管体验让 Wasp 为你拉起一个开箱即用的开发数据库。完全掌控通过DATABASE_URL指定连接串连接你自己准备的外部数据库。方式一使用 Wasp 提供的开发数据库运行以下命令即可启动一个默认的 PostgreSQL 开发数据库wasp start db你的 Wasp 应用会自动连接上去只需让wasp start db在后台持续运行即可。同时请确保已安装 Docker 且其可执行文件在你的PATH中端口5432没有被占用。这一机制在仓库中有完整的源码实现wasp-app-runner/src/db/postgres.ts 展示了 Wasp 如何拉取postgresDocker 镜像、以-p 5432:5432映射端口启动容器、设置POSTGRES_PASSWORD环境变量并通过循环执行pg_isready进行健康检查直到数据库就绪后才把生成的DATABASE_URL交给应用// wasp-app-runner/src/db/postgres.ts节选 const port 5432; const password devpass; // 启动容器、等待就绪后返回可用的连接串 return postgresql://postgres:${password}localhost:${port}/postgres as DatabaseConnectionUrl;源码还针对常见故障给出了明确提示如果端口被占用或容器残留会建议先清理旧容器或停用占用端口的进程这正是文档要求“端口 5432 空闲”的原因。:::tip 如果你想通过psql或 pgAdmin 等外部工具连接这个开发数据库连接凭据会在你运行wasp db start时打印在控制台最开头。 :::方式二连接已有数据库如果你想自建开发数据库或连接外部数据库可以通过DATABASE_URL环境变量告诉 WaspWasp 会把它当作连接串使用。最省事的做法是把DATABASE_URL写入项目根目录的.env.server文件文件不存在就新建一个例如DATABASE_URLpostgresql://user:passwordlocalhost:5432/mydb也可以直接在运行wasp命令时内联设置这对所有环境变量都适用DATABASE_URLmy-db-url wasp ...这个技巧特别适合让某条wasp命令针对特定数据库执行。例如DATABASE_URLproduction-db-url wasp db seed myProductionSeed这条命令会把种子数据写入一个全新的 staging 或生产数据库详见下文 播种数据库。从 SQLite 迁移到 PostgreSQL要让 Wasp 应用跑在生产环境就必须从 SQLite 切换到 PostgreSQL。迁移步骤如下第 1 步修改schema.prisma把 provider 改为postgresqldatasource db { provider postgresql url env(DATABASE_URL) } // ...第 2 步删除所有旧迁移和 SQLite 数据库文件。因为旧迁移是 SQLite 专属的无法用于 PostgreSQLrm -r migrations/ wasp cleanwasp clean是 Wasp 的 项目级命令用于清除项目生成的代码与构建产物。第 3 步确保你的新数据库已启动并保持运行连接方式见上文 连接数据库下一步需要用到它。第 4 步另开一个终端运行wasp db migrate-dev应用变更并创建新的初始迁移。第 5 步大功告成播种数据库Seeding the Database数据库播种Database seeding指用一些初始数据填充数据库的过程最常见的两种使用场景让开发数据库进入便于开发和测试的状态为任何环境dev、staging或prod初始化运行所需的必要数据例如为 Currency 表填充默认货币、为 Country 表填充所有国家。编写 Seed 函数你可以在app.db.seeds字段下定义一个数组数组里可以放任意数量的seed 函数app MyApp { // ... db: { seeds: [ import { devSeedSimple } from src/dbSeeds.js, import { prodSeed } from src/dbSeeds.js ] } }每个 seed 函数必须是一个异步函数接收唯一参数prisma——即用于与数据库交互的 Prisma Client 实例。这个实例与 Wasp 内部使用的 Prisma Client 是同一个。由于 seed 函数属于服务端代码它可以导入其他服务端函数。这意味着你可以方便地用 Action 来播种数据。下面是一个导入 Action 的 seed 函数示例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: await sanitizeAndSerializeProviderData({ hashedPassword: data.password }), }, }, }, }, }, }) return newUser }以上是 JavaScript 版本。若使用 TypeScriptWasp 提供了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 type { PrismaClient } from wasp/server 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: await sanitizeAndSerializeProviderDatausername({ hashedPassword: data.password }), }, }, }, }, }, }) return newUser }DbSeedFn的定义如下type DbSeedFn (prisma: PrismaClient) Promisevoid给devSeedSimple标注这个类型等价于告诉 TypeScript 两件事seed 函数的参数prisma是PrismaClient类型seed 函数的返回值是Promisevoid。注seed 函数的签名在不同版本间略有演进——0.18 及更早版本中它接收(prisma)参数而在 0.19 之后的 TypeScript Spec 版本中seed 函数变为无参函数直接通过import { prisma } from wasp/server访问客户端。编写时请以你所使用的 Wasp 版本为准本文以下内容以 0.18 文档为准。运行 Seed 函数运行wasp db seed如果你定义了多个 seed 函数Wasp 会交互式地询问你要运行哪一个。也可以直接指定名称一次到位例如wasp db seed devSeedSimple:::tip 你经常会在wasp db reset之后紧接着调用wasp db seed——清空数据库后马上填充初始数据是非常自然的组合。 :::从源码层面看种子执行的底层链路是这样的Wasp 在生成服务端代码时会把你在app.db.seeds中声明的每个 seed 函数收集起来见 waspc/src/Wasp/Generator/ServerGenerator/Db/Seed.hs其中定义了WASP_DB_SEED_NAME环境变量用于标识要运行的 seed 名称随后通过prisma db seed执行对应的 seed 脚本见 waspc/src/Wasp/Generator/DbGenerator/Jobs.hs。仓库中的端到端测试 waspc/e2e-tests/Tests/WaspDbSeedTest.hs 完整演示了这一流程测试项目声明了三个 seed 函数populateTasks插入数据、assertTasksEmpty断言表为空、assertTasksNotEmpty断言表非空依次运行wasp db seed name通过抛异常来校验每个 seed 是否按预期执行——这既是wasp db seed的用法示范也展示了 seed 函数在测试中的妙用。自定义 Prisma ClientWasp 通过 Prisma Client 与数据库交互。要自定义这个客户端可以在app.db.prismaSetupFn字段中定义一个返回 Prisma Client 实例的函数。这让你可以配置诸如 日志记录 或 客户端扩展 等能力app MyApp { title: My app, // ... db: { prismaSetupFn: import { setUpPrisma } from src/prisma } }import { PrismaClient } from prisma/client export const setUpPrisma () { const prisma new PrismaClient({ log: [query], }).$extends({ query: { task: { async findMany({ args, query }) { args.where { ...args.where, description: { not: { contains: hidden by setUpPrisma } }, } return query(args) }, }, }, }) return prisma }TypeScript 版本完全一致只是文件扩展名为.ts。上面的例子同时展示了两个能力通过log: [query]开启查询日志通过$extends给Task模型的findMany加上全局过滤逻辑。在生成器源码中prismaSetupFn被用来生成 SDK 的注册模块与类型增强——例如 waspc/src/Wasp/Generator/SdkGenerator/VirtualUserModules.hs 中的RegisteredPrismaSetupFn模块以及 waspc/src/Wasp/Generator/TypeAugmentationGenerator/App/Sdk.hs 中声明的dbClient类型。换言之你的自定义函数返回的 Prisma Client 类型会被 Wasp 的类型系统完整跟踪context.entities、wasp/server中导出的prisma等都与它保持一致。API 参考app.db是一个字典包含以下字段所有字段均为可选app MyApp { title: My app, // ... db: { seeds: [ import devSeed from src/dbSeeds ], prismaSetupFn: import { setUpPrisma } from src/prisma } }seeds: [ExtImport]定义可配合wasp db seed命令使用的 seed 函数用于向数据库填充初始数据。详见上文 播种数据库。prismaSetupFn: ExtImport定义用于设置 Prisma Client 实例的函数Wasp 期望它返回一个 Prisma Client 实例。可用来配置日志或客户端扩展import { PrismaClient } from prisma/client export const setUpPrisma () { const prisma new PrismaClient({ log: [query, info, warn, error], }) return prisma }播种相关的 CLI 命令使用以下命令运行 seed 函数wasp db seed如果只定义了一个 seed 函数直接运行它如果定义了多个会交互式地让你选择运行哪一个。wasp db seed seed-name运行指定名称的 seed 函数。这个名称就是app.db.seeds列表中import表达式所使用的标识符。例如对于如下定义的devSeedSimpleapp MyApp { // ... db: { seeds: [ // ... import { devSeedSimple } from src/dbSeeds.js, ] } }使用如下命令运行wasp db seed devSeedSimple小结数据库是任何 Web 应用的根基Wasp 通过 Prisma 这一层抽象让数据库操作变得简洁而类型安全。回顾本指南的核心要点开发起步默认 SQLite 零配置上手需要贴近生产环境时切到 PostgreSQL。连接策略开发期可用wasp start db让 Wasp 托管一个 Docker 化的 PostgreSQL要完全掌控时用.env.server中的DATABASE_URL指定连接串。生产迁移改 provider、清理旧迁移与产物、启动目标库、wasp db migrate-dev重建初始迁移四步完成切换。数据初始化通过app.db.seeds声明任意数量的 seed 函数用wasp db seed [name]灵活执行配合wasp db reset可快速重置并重建开发数据。深度定制用app.db.prismaSetupFn自定义 Prisma Client接入日志与客户端扩展且类型安全全程有保障。如需深入理解 Wasp 数据层其他部分可继续阅读 Entities、Operations、Automatic CRUD 与 Prisma schema file。 /output_article【免费下载链接】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),仅供参考