zenstack-migrate-from-v2
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMigrating from ZenStack V2 to V3
从ZenStack V2迁移到V3
ZenStack V3 is a major rewrite: the Prisma ORM engine is replaced with ZenStack's own engine built
on Kysely, while the ZModel schema stays largely compatible and the query API
stays PrismaClient-compatible. Supported databases: PostgreSQL, MySQL, SQLite.
Because V2 was Prisma-based, the migration has two layers: the generic Prisma→ZenStack changes, then
the V2-specific deltas below. For general setup/CLI see .
zenstack-project-setupZenStack V3是一次重大重构:Prisma ORM引擎被替换为基于Kysely构建的ZenStack自研引擎,同时ZModel架构保持高度兼容,查询API也与PrismaClient兼容。支持的数据库:PostgreSQL、MySQL、SQLite。
由于V2基于Prisma构建,迁移分为两层:首先是通用的Prisma→ZenStack变更,然后是以下V2专属的增量调整。通用配置/CLI相关内容可参考。
zenstack-project-setupStep 1 — Do the Prisma migration first
步骤1 — 先完成Prisma迁移
V2 ran on Prisma, so start with the skill (swap deps, move the
schema to , replace the client with , update generate/migrate
scripts). Then apply the V2-specific steps below.
zenstack-migrate-from-prismazenstack/schema.zmodelZenStackClientV2运行在Prisma之上,因此请先执行****技能(替换依赖、将架构文件移至、用替换客户端、更新生成/迁移脚本)。然后应用以下V2专属步骤。
zenstack-migrate-from-prismazenstack/schema.zmodelZenStackClientStep 2 — Rename ZenStack packages
步骤2 — 重命名ZenStack包
bash
npm uninstall zenstack @zenstackhq/runtime
npm install @zenstackhq/schema @zenstackhq/orm
npm install --save-dev @zenstackhq/cli| V2 | V3 |
|---|---|
| |
| |
| — | |
The CLI command moves from to (e.g. ).
zenstack <cmd>zen <cmd>zen generatebash
npm uninstall zenstack @zenstackhq/runtime
npm install @zenstackhq/schema @zenstackhq/orm
npm install --save-dev @zenstackhq/cli| V2 | V3 |
|---|---|
| |
| |
| — | |
CLI命令从改为(例如)。
zenstack <cmd>zen <cmd>zen generateStep 3 — Access control is now a plugin
步骤3 — 访问控制现在作为插件存在
In V2 access control was built into the runtime (). In V3 it's an opt-in plugin.
enhance(prisma)- Install it:
npm install @zenstackhq/plugin-policy - Declare it in the schema:
zmodel
plugin policy { provider = '@zenstackhq/plugin-policy' } - Wrap the client and bind the user per request:
ts
import { ZenStackClient } from '@zenstackhq/orm'; import { PolicyPlugin } from '@zenstackhq/plugin-policy'; export const db = new ZenStackClient(schema, { dialect }); export const authDb = db.$use(new PolicyPlugin()); // was: enhance(prisma, { user }) // per request: const userDb = authDb.$setAuth(user); // was: passing { user } to enhance()
See for the full policy/runtime model.
zenstack-access-control在V2中,访问控制内置在运行时()。V3中它是一个可选插件。
enhance(prisma)- 安装插件:
npm install @zenstackhq/plugin-policy - 在架构中声明:
zmodel
plugin policy { provider = '@zenstackhq/plugin-policy' } - 包装客户端并在每个请求中绑定用户:
ts
import { ZenStackClient } from '@zenstackhq/orm'; import { PolicyPlugin } from '@zenstackhq/plugin-policy'; export const db = new ZenStackClient(schema, { dialect }); export const authDb = db.$use(new PolicyPlugin()); // 原写法:enhance(prisma, { user }) // 每个请求中: const userDb = authDb.$setAuth(user); // 原写法:向enhance()传递{ user }
完整的策略/运行时模型可参考。
zenstack-access-controlStep 4 — Post-update policies: future()
→ post-update
+ before()
future()post-updatebefore()步骤4 — 更新后策略:future()
→ post-update
+ before()
future()post-updatebefore()V2 expressed post-update conditions with inside an rule. V3 uses a dedicated
operation, where bare field references mean the new values and reads the
old ones.
future()updatepost-updatebefore()zmodel
// V2
@@deny('update', future().ownerId != ownerId)
// V3
@@deny('post-update', ownerId != before().ownerId)V2中使用规则内的表示更新后条件。V3使用专用的操作,其中直接的字段引用代表新值,用于读取旧值。
updatefuture()post-updatebefore()zmodel
// V2
@@deny('update', future().ownerId != ownerId)
// V3
@@deny('post-update', ownerId != before().ownerId)Step 5 — Abstract models → types + mixins
步骤5 — 抽象模型 → 类型+混入
V2's + becomes a applied with (see
).
abstract modelextendstypewithzenstack-schema-modelingzmodel
// V2
abstract model Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post extends Timestamped { title String }
// V3
type Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post with Timestamped { title String }(Note: still exists in V3, but for polymorphism via , which is a different
feature — don't use it as a plain mixin replacement.)
extends@@delegateV2的 + 变为使用应用的(详见)。
abstract modelextendswithtypezenstack-schema-modelingzmodel
// V2
abstract model Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post extends Timestamped { title String }
// V3
type Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post with Timestamped { title String }(注意:V3中仍保留,但用于通过实现多态,这是一个不同的功能——不要将其用作普通混入的替代方案。)
extends@@delegateStep 6 — Server adapters
步骤6 — 服务器适配器
V3 requires you to pass an explicit ( or ), and the
client-supplying callback is renamed → :
apiHandlerRPCApiHandlerRestApiHandlergetPrismagetClientts
// V2
ZenStackMiddleware({ getPrisma: (req) => enhance(prisma, { user: getUser(req) }) });
// V3
ZenStackMiddleware({
apiHandler: new RPCApiHandler({ schema }),
getClient: (req) => authDb.$setAuth(getUser(req)),
});See for all frameworks and both API styles.
zenstack-crud-serverV3要求传递显式的(或),并且提供客户端的回调函数从重命名为:
apiHandlerRPCApiHandlerRestApiHandlergetPrismagetClientts
// V2
ZenStackMiddleware({ getPrisma: (req) => enhance(prisma, { user: getUser(req) }) });
// V3
ZenStackMiddleware({
apiHandler: new RPCApiHandler({ schema }),
getClient: (req) => authDb.$setAuth(getUser(req)),
});所有框架和两种API风格的相关内容可参考。
zenstack-crud-serverStep 7 — Client-side hooks (TanStack Query)
步骤7 — 客户端钩子(TanStack Query)
Flat hook names are replaced by hooks grouped under a client that mirrors the ORM:
ts
// V2
import { useFindManyUser } from '~/hooks';
const { data } = useFindManyUser({ where: { ... } });
// V3
import { useClientQueries } from '@zenstackhq/tanstack-query/react';
import { schema } from '~/zenstack/schema';
const client = useClientQueries(schema);
const { data } = client.user.useFindMany({ where: { ... } });SWR support was dropped in V3. See for the full TanStack Query setup.
zenstack-crud-server扁平化的钩子名称被替换为归属于镜像ORM的客户端下的钩子:
ts
// V2
import { useFindManyUser } from '~/hooks';
const { data } = useFindManyUser({ where: { ... } });
// V3
import { useClientQueries } from '@zenstackhq/tanstack-query/react';
import { schema } from '~/zenstack/schema';
const client = useClientQueries(schema);
const { data } = client.user.useFindMany({ where: { ... } });V3中已移除SWR支持。完整的TanStack Query配置可参考。
zenstack-crud-serverStep 8 — Other plugin/utility migrations
步骤8 — 其他插件/工具迁移
- Zod: now a utility rather than a plugin (see the zod utility docs).
- OpenAPI: folded into the automatic CRUD API handlers — generate a spec via
(see
apiHandler.generateSpec()).zenstack-crud-server - Custom plugins: the V3 plugin system is revised; consult the current plugin docs.
- Zod:现在是工具而非插件(详见Zod工具文档)。
- OpenAPI:整合到自动CRUD API处理器中——通过生成规范(详见
apiHandler.generateSpec())。zenstack-crud-server - 自定义插件:V3的插件系统已修订,请查阅当前插件文档。
After upgrading
升级完成后
Run , typecheck, and exercise your test suite / app. Confirm access control behaves as
expected now that it's an explicit + flow rather than V2's
implicit .
zen generate$use(new PolicyPlugin())$setAuth()enhance()运行,进行类型检查,并测试你的测试套件/应用。确认访问控制行为符合预期,现在它是显式的 + 流程,而非V2中的隐式。
zen generate$use(new PolicyPlugin())$setAuth()enhance()Reference docs
参考文档
Full ZenStack documentation for this topic is bundled under :
references/- migrate-v2.md — official "Migrating from ZenStack v2" guide
本主题的完整ZenStack文档打包在目录下:
references/- migrate-v2.md — 官方“从ZenStack v2迁移”指南