You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写支持Postgres与Sqlite的Drizzle TypeScript代码

实现Drizzle ORM同时适配PostgreSQL(生产)与SQLite(测试)

完全可以实现这个需求,Drizzle ORM本身支持多数据库适配,你可以通过两种方案达成目标:统一Schema适配多数据库,或是分库编写Schema并动态切换。以下是具体实现方式:


方案一:统一Schema适配多数据库

这种方案只需编写一套核心字段定义,再针对不同数据库用对应的表构造器包装,避免重复代码。

步骤1:编写通用字段定义

创建通用的Schema文件(比如src/schema/core.ts),只定义字段类型和约束,不关联具体数据库:

import { int, varchar, primaryKey, unique, notNull } from "drizzle-orm";

// 通用字段配置,不绑定特定数据库
export const usersFields = {
  id: int("id").primaryKey({ autoIncrement: true }),
  username: varchar("username", { length: 255 }).unique().notNull(),
};

步骤2:分别创建数据库连接与表实例

针对PostgreSQL和SQLite各自创建连接文件,用对应数据库的table构造器包装通用字段:

PostgreSQL连接(src/db/postgres.ts)

import { drizzle } from "drizzle-orm/node-postgres";
import { Client } from "pg";
import { pgTable } from "drizzle-orm/pg-core";
import { usersFields } from "../schema/core";

const client = new Client({ connectionString: process.env.DATABASE_URL });
await client.connect();

export const db = drizzle(client, {
  schema: {
    users: pgTable("users", usersFields),
  },
});

SQLite连接(src/db/sqlite.ts)

import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import { sqliteTable } from "drizzle-orm/sqlite-core";
import { usersFields } from "../schema/core";

const sqlite = new Database("test.db");
export const db = drizzle(sqlite, {
  schema: {
    users: sqliteTable("users", usersFields),
  },
});

步骤3:通过环境变量动态切换

创建入口文件(src/db/index.ts),根据环境变量选择使用的数据库实例:

import { db as postgresDb } from "./postgres";
import { db as sqliteDb } from "./sqlite";

// 根据NODE_ENV自动切换:测试环境用SQLite,生产用PostgreSQL
export const db = process.env.NODE_ENV === "test" ? sqliteDb : postgresDb;

方案二:分库编写Schema并动态切换

如果两种数据库的Schema差异较大(比如字段类型、约束逻辑不同),可以编写两套独立的Schema,再通过环境变量切换使用。

步骤1:编写分库Schema

分别创建PostgreSQL和SQLite专属的Schema文件:

PostgreSQL Schema(src/schema/postgres.ts)

import { pgTable, serial, varchar, unique, notNull } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(), // PostgreSQL用serial实现自增
  username: varchar("username", { length: 255 }).unique().notNull(),
});

SQLite Schema(src/schema/sqlite.ts)

import { sqliteTable, integer, text, unique, notNull } from "drizzle-orm/sqlite-core";

export const users = sqliteTable("users", {
  id: integer("id").primaryKey({ autoIncrement: true }), // SQLite用integer+autoIncrement
  username: text("username").unique().notNull(),
});

步骤2:动态导入并切换数据库

在数据库入口文件中,根据环境变量动态导入对应Schema和数据库连接:

let db;

if (process.env.NODE_ENV === "test") {
  // 测试环境:导入SQLite依赖与Schema
  const { drizzle } = await import("drizzle-orm/better-sqlite3");
  const Database = await import("better-sqlite3");
  const { users } = await import("../schema/sqlite");
  
  const sqlite = new Database("test.db");
  db = drizzle(sqlite, { schema: { users } });
} else {
  // 生产环境:导入PostgreSQL依赖与Schema
  const { drizzle } = await import("drizzle-orm/node-postgres");
  const { Client } = await import("pg");
  const { users } = await import("../schema/postgres");
  
  const client = new Client({ connectionString: process.env.DATABASE_URL });
  await client.connect();
  db = drizzle(client, { schema: { users } });
}

export { db };

注意事项

  1. 处理数据库差异:两种数据库的部分特性存在差异,比如自增字段类型、字符串类型(PostgreSQL的varchar vs SQLite的text)、高级约束等,需要在Schema中针对性处理。
  2. 迁移脚本:使用Drizzle Kit时,可以创建两份配置文件(比如drizzle.config.pg.ts和drizzle.config.sqlite.ts),分别生成对应数据库的迁移脚本:
    # 生成PostgreSQL迁移
    drizzle-kit generate:pg --config drizzle.config.pg.ts
    # 生成SQLite迁移
    drizzle-kit generate:sqlite --config drizzle.config.sqlite.ts
    

内容的提问来源于stack exchange,提问作者Michael Lorton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 07:15:10