TS 中文文档 TS 中文文档
指南
GitHub (opens new window)
指南
GitHub (opens new window)
  • 入门教程

    • TypeScript 手册
    • 基础知识
    • 日常类型
    • 类型缩小
    • 更多关于函数
    • 对象类型
    • 从类型创建类型
    • 泛型
    • Keyof 类型运算符
    • Typeof 类型运算符
    • 索引访问类型
    • 条件类型
    • 映射类型
    • 模板字面类型
    • 类
    • 模块
  • 参考手册

  • 项目配置

Drizzle ORM


If you know SQL, you know Drizzle ORM

Drizzle ORM is a TypeScript ORM for SQL databases designed with maximum type safety in mind. It comes with a drizzle-kit CLI companion for automatic SQL migrations generation. Drizzle ORM is meant to be a library, not a framework. It stays as an opt-in solution all the time at any levels.

The ORM main philosophy is "If you know SQL, you know Drizzle ORM". We follow the SQL-like syntax whenever possible, are strongly typed ground up and fail at compile time, not in runtime.

Drizzle ORM is being battle-tested on production projects by multiple teams 🚀Give it a try and let us know if you have any questions or feedback on Discord.

Feature list


Full type safety
Smart automated migrations generation
No ORM learning curve
SQL-like syntax for table definitions and queries
Best in class fully typed joins
Fully typed partial and non-partial selects of any complexity
Auto-inferring of TS types for DB models for selections and insertions separately
Zod schema generation
Zero dependencies

Supported databases


Database Status
:--- :---
PostgreSQL ✅
MySQL ✅
SQLite ✅
Cloudflare D1 ✅
libSQL ✅
Turso ✅
Vercel Postgres ✅
DynamoDB ⏳
MS SQL ⏳
CockroachDB ⏳

Our sponsors ❤️


Installation


  1. ``` shell
  2. npm install drizzle-orm
  3. npm install -D drizzle-kit
  4. ```

Feature showcase (PostgreSQL)


Note: don't forget to install pg and @types/pg packages for this example to work.


  1. ``` ts
  2. import { drizzle } from 'drizzle-orm/node-postgres';
  3. import { integer, pgTable, serial, text, timestamp, varchar } from 'drizzle-orm/pg-core';
  4. import { InferModel, eq, sql } from 'drizzle-orm';
  5. import { Pool } from 'pg';

  6. export const users = pgTable('users', {
  7.   id: serial('id').primaryKey(),
  8.   fullName: text('full_name').notNull(),
  9.   phone: varchar('phone', { length: 20 }).notNull(),
  10.   role: text('role', { enum: ['user', 'admin'] }).default('user').notNull(),
  11.   cityId: integer('city_id').references(() => cities.id),
  12.   createdAt: timestamp('created_at').defaultNow().notNull(),
  13.   updatedAt: timestamp('updated_at').defaultNow().notNull(),
  14. });

  15. export type User = InferModel<typeof users>;
  16. export type NewUser = InferModel<typeof users, 'insert'>;

  17. export const cities = pgTable('cities', {
  18.   id: serial('id').primaryKey(),
  19.   name: text('name').notNull(),
  20. });

  21. export type City = InferModel<typeof cities>;
  22. export type NewCity = InferModel<typeof cities, 'insert'>;

  23. const pool = new Pool({
  24.   connectionString: 'postgres://user:password@host:port/db',
  25. });

  26. const db = drizzle(pool);

  27. // Insert
  28. const newUser: NewUser = {
  29.   fullName: 'John Doe',
  30.   phone: '+123456789',
  31. };
  32. const insertedUsers /* : User[] */ = await db.insert(users).values(newUser).returning();
  33. const insertedUser = insertedUsers[0]!;

  34. const newCity: NewCity = {
  35.   name: 'New York',
  36. };
  37. const insertedCities /* : City[] */ = await db.insert(cities).values(newCity).returning();
  38. const insertedCity = insertedCities[0]!;

  39. // Update
  40. const updateResult /* : { updated: Date }[] */ = await db.update(users)
  41.   .set({ cityId: insertedCity.id, updatedAt: new Date() })
  42.   .where(eq(users.id, insertedUser.id))
  43.   .returning({ updated: users.updatedAt });

  44. // Select
  45. const allUsers /* : User[] */ = await db.select().from(users);

  46. // Select custom fields
  47. const upperCaseNames /* : { id: number; name: string }[] */ = await db
  48.   .select({
  49.     id: users.id,
  50.     name: sql<string>`upper(${users.fullName})`,
  51.   })
  52.   .from(users);

  53. // Joins
  54. // You wouldn't BELIEVE how SMART the result type is! 😱
  55. const allUsersWithCities = await db
  56.   .select({
  57.     id: users.id,
  58.     name: users.fullName,
  59.     city: {
  60.       id: cities.id,
  61.       name: cities.name,
  62.     },
  63.   })
  64.   .from(users)
  65.   .leftJoin(cities, eq(users.cityId, cities.id));

  66. // Delete
  67. const deletedNames /* : { name: string }[] */ = await db.delete(users)
  68.   .where(eq(users.id, insertedUser.id))
  69.   .returning({ name: users.fullName });
  70. ```

See full docs for further reference:

PostgreSQL
MySQL
SQLite
Last Updated: 2023-09-03 17:10:52