DrizzleORM v0.16.2 发布
Jan 21, 2023

Drizzle ORM - 是一种语义化的 TypeScript ORM,可用作查询构建器和作为 SQL 模式的真实源和用于自动生成迁移的 CLI。

自上一次的主要更新以来,我们已经添加了许多被请求的功能 🚀

🎉 PostgreSQL schemas

您现在可以声明要在此架构中创建的 PostgreSQL schemas 和表

// src/schema.ts
import { pgSchema } from "drizzle-orm-pg";

export const mySchema = pgSchema("my_schema");

export const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});
CREATE SCHEMA "my_schema";

CREATE TABLE IF NOT EXISTS "my_schema"."users" (
  "id" serial PRIMARY KEY NOT NULL,
  "name" text,
  "email" text
);

drizzle-kit 将自动生成所有需要的 SQL 迁移

drizzle-kit generate:pg --schema=src/schema.ts --out=migrations/ 

🎉 MySQL databases/schemas

您现在可以声明要在此中创建的 MySQL 数据库/模式 和表

// schema.ts
import { mysqlSchema } from "drizzle-orm-mysql";

const mySchema = mysqlSchema("my_schema");

const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});

drizzle-kit 将自动生成所有需要的 SQL 迁移 shell drizzle-kit generate:mysql --schema=src/schema.ts --out=migrations/

这将自动生成 SQL 迁移

CREATE DATABASE `my_schema`;

CREATE TABLE `my_schema`.`users` (
  `id` serial PRIMARY KEY NOT NULL,
  `name` text,
  `email` text
);

🎉 PostgreSQL introspect

您现在可以使用 drizzle-kit 在几秒钟内从现有的 PostgreSQL 数据库中提取数据库模式,无需切换任何现有的 ORM 或原始 SQL。它支持:

  • 枚举
  • 具有所有本地和非本地列的表
  • 索引
  • 外键、自引用和循环外键
  • 模式
drizzle-kit introspect:pg --out=migrations/ --connectionString=postgresql://user:pass@host:port/db_name

它将为您打印 schema.ts

export const myEnum = pgEnum("my_enum", ["one", "two", "three"]);
export const mySchema = pgSchema("my_schema");

export const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});

export const users2 = pgTable("users2", {
  id: serial("id").primaryKey(),
  name: varchar("name2"),
  enum: myEnum("enum"),
});

export const allColumns = pgTable("all_columns", {
  sm: smallint("smallint"),
  smdef: smallint("smallint_def").default(10),
  int: integer("integer"),
  intdef: integer("integer_def").default(10),
  numeric: numeric("numeric"),
  numeric2: numeric("numeric2", { precision: 7 }),
  numeric3: numeric("numeric3", { scale: 7 }),
  numeric4: numeric("numeric4", { precision: 7, scale: 7 }),
  numericdef: numeric("numeridef").default("100"),
  bigint: bigint("bigint", { mode: "number" }),
  bigintdef: bigint("bigint", { mode: "number" }).default(100),
  bool: boolean("boolean"),
  booldef: boolean("boolean_def").default(true),
  text: text("text"),
  textdef: text("textdef").default("text"),
  varchar: varchar("varchar"),
  varchardef: varchar("varchardef").default("text"),
  serial: serial("serial"),
  bigserial: bigserial("bigserial", { mode: "bigint" }),
  decimal: decimal("decimal", { precision: 100, scale: 2 }),
  decimaldef: decimal("decimaldef", { precision: 100, scale: 2 }).default(
    "100.0",
  ),
  doublePrecision: doublePrecision("decimal"),
  doublePrecisiondef: doublePrecision("decimaldef").default(100.0),
  real: real("real"),
  realdef: real("decimaldef").default(100.0),
  json: json<{ attr: string }>("json"),
  jsondef: json<{ attr: string }>("jsondef").default({ attr: "value" }),
  jsonb: jsonb<{ attr: string }>("jsonb"),
  jsonbdef: jsonb<{ attr: string }>("jsonbdef").default({ attr: "value" }),
  time: time("time"),
  time2: time("time2", { precision: 6, withTimezone: true }),
  timedefnow: time("timedefnow").defaultNow(),
  timestamp: timestamp("timestamp"),
  timestamp2: timestamp("timestamp2", { precision: 6, withTimezone: true }),
  timestamp3: timestamp("timestamp3", { withTimezone: true }),
  timestamp4: timestamp("timestamp4", { precision: 4 }),
  timestampdef: timestamp("timestampdef").defaultNow(),
  date: date("date", { mode: "date" }),
  datedef: date("datedef").defaultNow(),
  interval: interval("interval"),
  intervaldef: interval("intervaldef").default("10 days"),
});

export const cyclic1 = pgTable("cyclic1", {
  id: serial("id").primaryKey(),
  ext2: integer("ext2").references(() => cyclic2.id),
});

export const cyclic2 = pgTable("cyclic2", {
  id: serial("id").primaryKey(),
  ext1: integer("ext1").references((): AnyPgColumn => cyclic1.id),
});

export const example = pgTable(
  "example",
  {
    id: serial("id").primaryKey(),
    reportsTo: integer("reports_to"),
  },
  (table) => {
    return {
      reportsToFK: foreignKey({
        columns: [table.reportsTo],
        foreignColumns: [table.id],
      }),
    };
  },
);

🎉 Postgres.js 驱动支持

我们完全支持了 postgres.js,它轻量且速度快 🚀

// schema.ts
import { pgTable, serial, text, varchar } from "drizzle-orm-pg";
export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  fullName: text("full_name"),
  phone: varchar("phone", { length: 256 }),
});

// index.ts
import { drizzle, PostgresJsDatabase } from "drizzle-orm-pg/postgres.js";
import postgres from "postgres";
import { users } from "./schema";

const client = postgres(connectionString);
const db: PostgresJsDatabase = drizzle(client);

const allUsers = await db.select(users);

完整的 PostgreSQL 文档请参见 这里

🎉 PostgreSQL 和 MySQL 类型

我们为您提供了一些有用的操作符,用于创建所需的非本地 PostgreSQL 或 MySQL 类型

// PostgreSQL
const customText = customType<{ data: string }>({
  dataType() {
    return "text";
  },
});

const usersTable = pgTable("users", {
  name: customText("name").notNull(),
});

// MySQL
const customText = customType<{ data: string }>({
  dataType() {
    return "text";
  },
});

const usersTable = mysqlTable("users", {
  name: customText("name").notNull(),
});
Become a Gold Sponsor