视图

使用 Drizzle ORM,你可以通过多种方式声明视图。

你可以声明需要创建的视图,也可以声明数据库中已经存在的视图。

你可以使用内联 query builder 语法、standalone query builder,以及原始 sql 操作符来声明视图语句。

当视图使用内联或独立的查询构建器创建时,视图列的模式会自动推断;
而当你使用 sql 时,则需要显式声明视图列的模式。

声明视图

schema.ts
import { integer, text, sqliteView, sqliteTable } from "drizzle-orm/sqlite-core";
import { eq } from 'drizzle-orm';

export const user = sqliteTable("user", {
  id: integer().primaryKey({ autoIncrement: true }),
  name: text(),
  email: text(),
  password: text(),
  role: text().$type<"admin" | "customer">(),
  createdAt: integer("created_at"),
  updatedAt: integer("updated_at"),
});

export const userView = sqliteView("user_view").as((qb) => qb.select().from(user));
export const customersView = sqliteView("customers_view").as((qb) => qb.select().from(user).where(eq(user.role, "customer")));
CREATE VIEW `user_view` AS select "id", ... from "user";
CREATE VIEW `customers_view` AS select "id", ... from "user" where "user"."role" = 'customer';

你也可以使用 standalone query builder 来声明视图,它的工作方式完全相同:

schema.ts
import { integer, text, sqliteView, sqliteTable, QueryBuilder } from "drizzle-orm/sqlite-core";
import { eq } from 'drizzle-orm';

const qb = new QueryBuilder();

export const user = sqliteTable("user", {
  id: integer().primaryKey({ autoIncrement: true }),
  name: text(),
  email: text(),
  password: text(),
  role: text().$type<"admin" | "customer">(),
  createdAt: integer("created_at"),
  updatedAt: integer("updated_at"),
});

export const userView = sqliteView("user_view").as(() => qb.select().from(user));
export const customerView = sqliteView("customers_view").as((qb) => qb.select().from(user).where(eq(user.role, "customer")));
CREATE VIEW `user_view` AS select "id", ... from "user";
CREATE VIEW `customers_view` AS select "id", ... from "user" where "user"."role" = 'customer';

使用原始 SQL 声明视图

当你需要使用查询构建器不支持的语法来声明视图时,
你可以直接使用 sql 操作符,并显式指定视图列的模式。

// 常规视图
const newYorkers = sqliteView('new_yorkers', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  cityId: integer('city_id').notNull(),
}).as(sql`select * from ${users} where ${eq(users.cityId, 1)}`);

声明已有视图

当你只能以只读方式访问数据库中已有的视图时,应使用 .existing() 视图配置,
drizzle-kit 会忽略它,并且不会在生成的迁移中生成 create view 语句。

export const user = sqliteTable("user", {
  id: integer().primaryKey({ autoIncrement: true }),
  name: text(),
  email: text(),
  password: text(),
  role: text().$type<"admin" | "customer">(),
  createdAt: timestamp("created_at"),
  updatedAt: timestamp("updated_at"),
});

// 常规视图
export const trimmedUser = sqliteView("trimmed_user", {
  id: integer("id"),
  name: text("name"),
  email: text("email"),
}).existing();