关于 drizzle-nextjs-postgres
面向在 Next.js App Router 中使用 Drizzle ORM 和 PostgreSQL 的开发者的参考技能。36 条规则涵盖数据库访问、缓存、模式变更、事务和查询构建,并针对指定版本提供指导。
主要功能
- 01七类共 36 条规则
- 02驱动选择与连接池指导
- 03Server Component 读取与缓存
- 04Server Action 变更实践
- 05模式、迁移和事务指导
- 06PostgreSQL 查询构建建议
适用场景
- 01设置 Drizzle 数据库模块
- 02检查 Server Component 读取缓存
- 03规划 PostgreSQL 模式变更
- 04排查慢查询或连接池问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill drizzle-nextjs-postgres安装后在 Claude Code 中输入/drizzle-nextjs-postgres确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mdconn-disable-prepare-behind-transaction-pooler.mdconn-driver-choice-follows-transactions.mdconn-pass-schema-for-relational-queries.mdconn-pool-sizing-for-serverless.mdconn-server-only-db-module.mdconn-singleton-across-hmr.mdmigrate-add-constraints-not-valid-then-validate.mdmigrate-concurrent-index-outside-transaction.mdmigrate-generate-not-push.mdmigrate-map-renames-explicitly.mdmigrate-run-in-deploy-step-not-at-runtime.mdmut-after-for-post-response-writes.mdmut-authorize-inside-the-action.mdmut-updatetag-vs-revalidatetag.mdquery-count-scans-the-table.mdquery-execute-shape-is-driver-dependent.mdquery-keyset-not-offset.mdquery-not-in-null-trap.mdquery-prepared-statements-need-names.mdrsc-dedupe-with-react-cache.mdrsc-no-request-apis-inside-use-cache.mdrsc-node-runtime-not-edge.mdrsc-suspense-around-uncached-reads.mdrsc-use-cache-is-per-instance-memory.mdrsc-use-cache-replaces-unstable-cache.mdschema-bigint-mode-truncation.md详细介绍
Next.js 中的 Drizzle + PostgreSQL
适用于 Next.js App Router 中 PostgreSQL 上 Drizzle ORM 的库参考技能 — 涵盖 7 个类别中的 36 条规则。每条规则都会指出它要纠正的错误默认做法;对于能力足够的模型本来就能做对的事情,这里不会专门列出规则。
此技能内容完备:它包含 Postgres + Next.js 开发者所需的迁移工作流和类型推断规则,即便底层错误默认做法并非 Postgres 特有,也会一并涵盖,因此你无需在任务进行中加载第二个技能。部分规则与配套的 drizzle-sqlite 技能有意重叠(针对相同的错误默认做法,只是结合此处的上下文重新表述);其余规则则涉及仅在 PostgreSQL 方言中存在,或因代码运行于 App Router 而有所不同的决策。
固定使用 drizzle-orm 0.45.2、drizzle-kit 0.31.10、Next.js 16.2.11、PostgreSQL 14+。
适用场景
- 编写或审查
lib/db模块 — 驱动选择、连接池、单例、server-only - 在 Server Component、Route Handler 或
generateMetadata中使用db.select()/db.query.*获取数据 - 决定缓存策略:
use cache、cacheLife、cacheTag、Reactcache(),或不缓存 - 编写修改行数据的 Server Action,并使其失效读路径缓存的内容
- 定义或修改
pgTable— 列类型、索引、枚举、约束 - 运行
drizzle-kit generate/migrate/push,或手动编辑生成的.sql文件 - 使用
db.transaction()包装操作,或排查竞态、死锁、连接池耗尽问题 - 审查在本地运行正常、但在生产环境变慢的列表、计数或分页查询
规则类别
| # | 类别 | 前缀 | 涵盖内容 |
|---|---|---|---|
| 1 | 客户端构建与驱动选择 | conn- | HMR 下的单例、无服务器连接池大小、连接池代理、驱动能力、server-only、传入 schema |
| 2 | Server Component 中的读取 | rsc- | Suspense 边界、use cache / cacheLife / cacheTag、请求去重、瀑布流、运行时选择 |
| 3 | Server Action 与变更 | mut- | Action 中的授权和验证、缓存失效、延迟写入 |
| 4 | Postgres 模式定义 | schema- | timestamptz、identity 列、text 与 varchar、numeric、jsonb、bigint 模式、表配置、枚举 |
| 5 | 迁移与模式变更安全性 | migrate- | generate 与 push、并发索引、迁移运行位置、重命名、锁安全约束 |
| 6 | 事务与池化连接 | tx- | 持有事务的连接成本、行锁、序列化重试 |
| 7 | Postgres 查询构建 | query- | 键集分页、计数成本、依赖驱动的 execute 返回形态、NULL 语义、预处理语句 |
快速参考
1. 客户端构建与驱动选择
conn-singleton-across-hmr— 在globalThis上缓存连接池,避免开发热重载耗尽连接conn-pool-sizing-for-serverless— 连接总数 = 实例数 × max;max: 1并无帮助conn-disable-prepare-behind-transaction-pooler— 在 PgBouncer/Supavisor 事务模式后使用postgres(url, { prepare: false })conn-driver-choice-follows-transactions—neon-http会在db.transaction上抛出异常;db.batch()仍然是原子的。根据“先读取 — 再决策 — 后写入”选择驱动conn-server-only-db-module— 在客户端模块中导入import 'server-only',而不是在模式文件中导入conn-pass-schema-for-relational-queries— 不传入{ schema }时db.query为空,且with需要relations()
2. 在服务端组件中读取数据
rsc-suspense-around-uncached-reads— 在页面顶部查询,会让路由失去静态外壳rsc-use-cache-replaces-unstable-cache—use cache+cacheLife+cacheTag取代unstable_cache和分段配置rsc-no-request-apis-inside-use-cache—cookies()在use cache内会抛出异常;应将租户 ID 作为参数传入rsc-use-cache-is-per-instance-memory—use cache是每个实例的内存缓存,不是持久化查询缓存rsc-dedupe-with-react-cache— Reactcache()可在 layout、page 和 metadata 之间对同一查询去重rsc-node-runtime-not-edge— Cache Components 不支持runtime = 'edge'
3. Server Actions 与变更
mut-authorize-inside-the-action— Action 是公开的 POST 端点;应在其函数体中检查身份验证和输入mut-updatetag-vs-revalidatetag— 对于读写一致性,使用updateTag;对于 SWR,使用revalidateTag(tag, 'max')mut-after-for-post-response-writes—after()将审计和分析写入移出响应路径
4. Postgres 架构定义
schema-timestamptz-not-timestamp— 裸timestamp()不表示一个时间点schema-identity-not-serial— 使用generatedAlwaysAsIdentity(),而非serial()schema-text-not-varchar-length— 使用text(),除非长度限制确实是业务规则schema-numeric-is-a-string—numeric推断为string;应将金额存为整数分schema-jsonb-with-dollar-type— 使用jsonb以支持索引,使用$type<>()定义形状schema-bigint-mode-truncation—mode: 'number'会在超过 2^53 后静默舍入schema-table-extras-are-an-array—pgTable的第三个参数返回数组;对象形式已弃用schema-enum-values-are-append-only— 新枚举值要等事务提交后才能使用
5. 迁移与架构变更安全
migrate-generate-not-push—push会应用未经审查的差异;generate会生成可供阅读的文件migrate-concurrent-index-outside-transaction—migrate()会在一个事务中运行所有文件,因此CONCURRENTLY在其中会失败migrate-run-in-deploy-step-not-at-runtime— 并发冷启动会争抢运行migrate();应在流量进入前运行一次migrate-map-renames-explicitly— 在提示词中选择“create column”会丢弃被重命名列的数据migrate-add-constraints-not-valid-then-validate—NOT VALID会跳过阻塞扫描;应在第二次部署中验证
6. 事务与连接池
tx-no-external-io-inside— 事务会固定一个连接;在事务内进行网络调用会耗尽连接池tx-lock-rows-for-read-modify-write—read committed允许两个事务读取同一行过时的数据tx-retry-serialization-failures—serializable会以 SQLSTATE40001中止,并要求重试
7. Postgres 查询构建
query-keyset-not-offset—OFFSET会读取并丢弃它跳过的每一行query-count-scans-the-table— Postgres 不存储行数;count(*)每次都会遍历行query-execute-shape-is-driver-dependent— 原始db.execute()在 node-postgres 中返回.rows,在 postgres-js 中则返回一个普通数组query-not-in-null-trap— 子查询中有一个 NULL,就会导致NOT IN什么也不返回query-prepared-statements-need-names—.prepare()需要名称,而事务池化器会使其失效
使用方法
遇到相关决策时,阅读对应的参考文件。每条规则都会指出它要纠正的错误默认做法,然后展示规范做法(只有当错误做法确实会造成陷阱时,才会对比错误与正确做法)。
相关技能
drizzle-sqlite— 同一 ORM 用于 SQLite 系列后端;涵盖本技能有意省略的方言无关查询构建规则nextjs— 数据层之外的 App Router 模式relational-database-design— 选择本技能教你声明的架构
参考文件
| 文件 | 描述 |
|---|---|
| references/_sections.md | 分类定义与排序 |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本与来源引用 |
评论
支持 Markdown