Loading...
Loading...
Compare original and translation side by side
Quick Guide: Use Drizzle ORM for type-safe queries, Neon serverless Postgres for edge-compatible connections. Schema-first design with automatic TypeScript types. Use RQB v2 withand object-baseddefineRelations()syntax. Relational queries withwhereavoid N+1 problems. Use transactions for atomic operations..with()
快速指南: 使用Drizzle ORM实现类型安全查询,借助Neon无服务器Postgres实现边缘兼容连接。采用Schema-first设计,自动生成TypeScript类型。使用RQB v2的和基于对象的defineRelations()语法。通过where实现关联查询,避免N+1问题。使用事务处理原子操作。.with()
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,, named constants)import type
casing: 'snake_case'txdb.with()defineRelations()relations()所有代码必须遵循CLAUDE.md中的项目规范(短横线命名法、命名导出、导入顺序、、命名常量)import type
casing: 'snake_case'txdb.with()defineRelations()relations()export const db = drizzle(sql, {
schema,
casing: "snake_case", // Maps camelCase JS to snake_case SQL
});DATABASE_URLcasing: "snake_case"neon()Poolexport const db = drizzle(sql, {
schema,
casing: "snake_case", // 将驼峰式JS字段映射为下划线式SQL字段
});DATABASE_URLcasing: "snake_case"neon()Poolexport const companies = pgTable("companies", {
id: uuid("id").primaryKey().defaultRandom(),
name: varchar("name", { length: 255 }).notNull(),
slug: varchar("slug", { length: 255 }).unique(),
deletedAt: timestamp("deleted_at"), // Soft delete
createdAt: timestamp("created_at").defaultNow(),
});pgEnum()createdAtupdatedAtdeletedAtonDelete: "cascade"uuid().defaultRandom()integer().generatedAlwaysAsIdentity()export const companies = pgTable("companies", {
id: uuid("id").primaryKey().defaultRandom(),
name: varchar("name", { length: 255 }).notNull(),
slug: varchar("slug", { length: 255 }).unique(),
deletedAt: timestamp("deleted_at"), // 软删除
createdAt: timestamp("created_at").defaultNow(),
});pgEnum()createdAtupdatedAtdeletedAtonDelete: "cascade"uuid().defaultRandom()integer().generatedAlwaysAsIdentity().with().with().with()const job = await db.query.jobs.findFirst({
where: and(eq(jobs.id, jobId), isNull(jobs.deletedAt)),
with: {
company: { with: { locations: true } },
jobSkills: { with: { skill: true } },
},
});
// Result is fully typed: job.company.name, job.jobSkills[0].skill.namedb.query.with()db.select()isNull(deletedAt).with()const job = await db.query.jobs.findFirst({
where: and(eq(jobs.id, jobId), isNull(jobs.deletedAt)),
with: {
company: { with: { locations: true } },
jobSkills: { with: { skill: true } },
},
});
// 返回结果完全类型化:job.company.name, job.jobSkills[0].skill.namedb.query.with()db.select()isNull(deletedAt)generatepushgeneratepushdbtx.with()casing: 'snake_case'relations()defineRelations()whereorderByisNull(deletedAt)enableRLS()pgTable.withRLS()drizzle-zoddrizzle-orm/zoddbtx.with()casing: 'snake_case'relations()defineRelations()whereorderByisNull(deletedAt)enableRLS()pgTable.withRLS()drizzle-zoddrizzle-orm/zodAll code must follow project conventions in CLAUDE.md
casing: 'snake_case'txdb.with()defineRelations()relations()所有代码必须遵循CLAUDE.md中的项目规范
casing: 'snake_case'txdb.with()defineRelations()relations()