2024 主流的 ts orm 工具,类型安全,无二进制文件依赖,支持各种 serverless 运行时和数据库服务。
初始化
根据环境安装、初始化、编写配置文件等。
比如使用 neon ,可参照:
https://orm.drizzle.team/docs/tutorials/drizzle-with-neon
npm i drizzle-orm @neondatabase/serverless
npm i -D drizzle-kit dotenv
编辑配置文件:
import { config } from 'dotenv';
import { defineConfig } from "drizzle-kit";
config({ path: '.env.local' });
export default defineConfig({
schema: "./src/schema.ts",
out: "./migrations",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
项目中导出客户端:
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
import * as schema from './schema';
export const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle({ client: sql, schema });
schema
根据文档 Manage schema 的部分进行设置。
- Data types 字段类型 https://orm.drizzle.team/docs/column-types/pg
- Indexes & Constraints 键 https://orm.drizzle.team/docs/indexes-constraints
- Relations 关联关系 https://orm.drizzle.team/docs/relations
定义表:
import { integer, pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
export const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: integer('age').notNull(),
email: text('email').notNull().unique(),
});
export const postsTable = pgTable('posts_table', {
id: serial('id').primaryKey(),
title: text('title').notNull(),
content: text('content').notNull(),
userId: integer('user_id')
.notNull()
.references(() => usersTable.id, { onDelete: 'cascade' }),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at')
.notNull()
.$onUpdate(() => new Date()),
});
获取对应类型:
$inferInsert
插入数据库的类型,比如某些字段允许为空$inferSelect
查询出来的类型,全量字段
export type InsertUser = typeof usersTable.$inferInsert;
export type SelectUser = typeof usersTable.$inferSelect;
export type InsertPost = typeof postsTable.$inferInsert;
export type SelectPost = typeof postsTable.$inferSelect;
generate 与 migrate
通过 drizzle-kit 进行。
https://orm.drizzle.team/docs/kit-overview
先执行 generate ,再执行 migrate
drizzle-kit generate
drizzle-kit migrate
支持指定配置文件,应用于多个环境:
drizzle-kit migrate --config=drizzle-dev.drizzle.config
增删改查
在文档 Access your data 处
- Select 查
- Insert 创建
- Update 更新
- Delete 删除
- Filters 查询条件
- Utils 工具,主要是查数量
- Joins 关联
- Magic sql operator 自定义 sql 语句
基础增删改成:
db.insert(usersTable).values(data);
db.select().from(usersTable);
db.select().from(usersTable).where(eq(usersTable.id, id));
db.update(postsTable).set(data).where(eq(postsTable.id, id));
db.delete(usersTable).where(eq(usersTable.id, id));
分页+关联查询+排序:
db.select({
...getTableColumns(usersTable),
postsCount: count(postsTable.id),
})
.from(usersTable)
.leftJoin(postsTable, eq(usersTable.id, postsTable.userId))
.groupBy(usersTable.id)
.orderBy(asc(usersTable.id))
.limit(pageSize)
.offset((page - 1) * pageSize);
查询近24小时文章:
db
.select({
id: postsTable.id,
title: postsTable.title,
})
.from(postsTable)
.where(between(postsTable.createdAt, sql`now() - interval '1 day'`, sql`now()`))
.orderBy(asc(postsTable.title), asc(postsTable.id))
.limit(pageSize)
.offset((page - 1) * pageSize);
zod
https://orm.drizzle.team/docs/zod
定义:
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
// 用于创建的验证
const insertUserSchema = createInsertSchema(users);
// 用于查询的验证
const selectUserSchema = createSelectSchema(users);
// 覆盖某个字段的规则
const insertUserSchema = createInsertSchema(users, {
role: z.string(),
});
// 拓展某个字段的规则
const insertUserSchema = createInsertSchema(users, {
id: (schema) => schema.id.positive(),
email: (schema) => schema.email.email(),
role: z.string(),
});
// 创建后选择 zod Schema 的某些字段
const requestSchema = insertUserSchema.pick({ name: true, email: true });
// 组合新的字段
const registorySchema = insertUserSchema.pick({ name: true, email: true }).extend({
password: z.string().min(6).max(32)
})