Skip to main content
Neon 是一个完全托管的无服务器 Postgres,它将计算和存储分离,提供自动扩展、分支和无底洞存储等功能。Neon 可以直接通过 Bun 使用 @neondatabase/serverless 驱动,或者通过像 Drizzle 这样的 ORM 来使用。 Drizzle ORM 同时支持类似 SQL 的“查询构建器”API 和类似 ORM 的 Queries API。首先创建一个项目目录,使用 bun init 初始化该目录,并安装 Drizzle 和 Neon 无服务器驱动
terminal
mkdir bun-drizzle-neon
cd bun-drizzle-neon
bun init -y
bun add drizzle-orm @neondatabase/serverless
bun add -D drizzle-kit

创建一个 .env.local 文件,并添加你的 Neon Postgres 连接字符串
.env.local
DATABASE_URL=postgresql://usertitle:[email protected]/neondb?sslmode=require

我们将使用 Neon 无服务器驱动连接 Neon 数据库,并用 Drizzle 包装为一个数据库实例。
https://mintcdn.com/ikxin/RzFFGbzo0-4huILA/icons/typescript.svg?fit=max&auto=format&n=RzFFGbzo0-4huILA&q=85&s=a3dffd2241f05776d3bd25171d0c5a79db.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

// Bun 会自动从 .env.local 加载 DATABASE_URL
// 参考:https://bun.com/docs/runtime/environment-variables 获取更多信息
const sql = neon(process.env.DATABASE_URL!);

export const db = drizzle(sql);

为了演示数据库的使用,在 index.ts 中添加以下代码。
https://mintcdn.com/ikxin/RzFFGbzo0-4huILA/icons/typescript.svg?fit=max&auto=format&n=RzFFGbzo0-4huILA&q=85&s=a3dffd2241f05776d3bd25171d0c5a79index.ts
import { db } from "./db";
import { sql } from "drizzle-orm";

const query = sql`select 'hello world' as text`;
const result = await db.execute(query);
console.log(result.rows);

然后使用 Bun 运行 index.ts
terminal
bun run index.ts
[
  {
    text: "hello world",
  }
]

我们可以使用 Drizzle ORM 的原语定义数据库架构。创建一个 schema.ts 文件,并添加以下代码。
https://mintcdn.com/ikxin/RzFFGbzo0-4huILA/icons/typescript.svg?fit=max&auto=format&n=RzFFGbzo0-4huILA&q=85&s=a3dffd2241f05776d3bd25171d0c5a79schema.ts
import { pgTable, integer, serial, text, timestamp } from "drizzle-orm/pg-core";

export const authors = pgTable("authors", {
  id: serial("id").primaryKey(),
  title: text("name").notNull(),
  bio: text("bio"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
});

然后使用 drizzle-kit CLI 生成初始的 SQL 迁移文件。
bunx drizzle-kit generate --dialect postgresql --schema ./schema.ts --out ./drizzle

这将在项目中创建一个名为 drizzle 的新目录,包含 .sql 迁移文件和 meta 目录。
File Tree
drizzle
├── 0000_aspiring_post.sql
└── meta
    ├── 0000_snapshot.json
    └── _journal.json

我们可以通过一个简单的 migrate.ts 脚本来执行这些迁移。该脚本会新建一个与 Neon 数据库的连接,并执行 drizzle 目录中所有尚未执行的迁移。
migrate.ts
import { db } from "./db";
import { migrate } from "drizzle-orm/neon-http/migrator";

const main = async () => {
  try {
    await migrate(db, { migrationsFolder: "drizzle" });
    console.log("Migration completed");
  } catch (error) {
    console.error("Error during migration:", error);
    process.exit(1);
  }
};

main();

可以用 bun 运行此脚本来执行迁移。
terminal
bun run migrate.ts
Migration completed

现在,我们可以为数据库添加一些数据。创建一个 seed.ts 文件,内容如下。
https://mintcdn.com/ikxin/RzFFGbzo0-4huILA/icons/typescript.svg?fit=max&auto=format&n=RzFFGbzo0-4huILA&q=85&s=a3dffd2241f05776d3bd25171d0c5a79seed.ts
import { db } from "./db";
import * as schema from "./schema";

async function seed() {
  await db.insert(schema.authors).values([
    {
      title: "J.R.R. Tolkien",
      bio: "中土世界的创作者,《指环王》的作者。",
    },
    {
      title: "George R.R. Martin",
      bio: "史诗奇幻系列《冰与火之歌》的作者。",
    },
    {
      title: "J.K. Rowling",
      bio: "《哈利·波特》系列的创作者。",
    },
  ]);
}

async function main() {
  try {
    await seed();
    console.log("Seeding completed");
  } catch (error) {
    console.error("Error during seeding:", error);
    process.exit(1);
  }
}

main();

然后运行此文件。
terminal
bun run seed.ts
Seeding completed

现在我们已经有了带有架构和示例数据的数据库,可以使用 Drizzle 进行查询。将 index.ts 的内容替换为以下代码。
https://mintcdn.com/ikxin/RzFFGbzo0-4huILA/icons/typescript.svg?fit=max&auto=format&n=RzFFGbzo0-4huILA&q=85&s=a3dffd2241f05776d3bd25171d0c5a79index.ts
import * as schema from "./schema";
import { db } from "./db";

const result = await db.select().from(schema.authors);
console.log(result);

接着运行该文件。你应该看到我们插入的三位作者信息。
terminal
bun run index.ts
[
  {
    id: 1,
    title: "J.R.R. Tolkien",
    bio: "中土世界的创作者,《指环王》的作者。",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 2,
    title: "George R.R. Martin",
    bio: "史诗奇幻系列《冰与火之歌》的作者。",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 3,
    title: "J.K. Rowling",
    bio: "《哈利·波特》系列的创作者。",
    createdAt: 2024-05-11T10:28:46.029Z,
  }
]

本示例使用了 Neon 无服务器驱动的基于 HTTP 的 SQL 功能。Neon 的无服务器驱动还提供 ClientPool 构造器,以支持会话、交互式事务和兼容 node-postgres。详见 Neon 文档 获取完整介绍。 更多关于 Drizzle ORM 的使用文档,请参考 Drizzle 官网