> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 Drizzle ORM 连接 Neon Postgres

[Neon](https://neon.tech/) 是一个完全托管的无服务器 Postgres，它将计算和存储分离，提供自动扩展、分支和无底洞存储等功能。Neon 可以直接通过 Bun 使用 `@neondatabase/serverless` 驱动，或者通过像 `Drizzle` 这样的 ORM 来使用。

Drizzle ORM 同时支持类似 SQL 的“查询构建器”API 和类似 ORM 的 [Queries API](https://orm.drizzle.team/docs/rqb)。首先创建一个项目目录，使用 `bun init` 初始化该目录，并安装 Drizzle 和 [Neon 无服务器驱动](https://github.com/neondatabase/serverless/)。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
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 连接字符串](https://neon.tech/docs/connect/connect-from-any-app)。

```ini .env.local icon="settings" theme={"theme":{"light":"github-light","dark":"dracula"}}
DATABASE_URL=postgresql://usertitle:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require
```

***

我们将使用 Neon 无服务器驱动连接 Neon 数据库，并用 Drizzle 包装为一个数据库实例。

```ts db.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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` 中添加以下代码。

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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`。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
```

```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
[
  {
    text: "hello world",
  }
]
```

***

我们可以使用 Drizzle ORM 的原语定义数据库架构。创建一个 `schema.ts` 文件，并添加以下代码。

```ts schema.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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 迁移文件。

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
bunx drizzle-kit generate --dialect postgresql --schema ./schema.ts --out ./drizzle
```

***

这将在项目中创建一个名为 `drizzle` 的新目录，包含 `.sql` 迁移文件和 `meta` 目录。

```txt File Tree icon="folder-tree" theme={"theme":{"light":"github-light","dark":"dracula"}}
drizzle
├── 0000_aspiring_post.sql
└── meta
    ├── 0000_snapshot.json
    └── _journal.json
```

***

我们可以使用 `migrate.ts` 脚本来执行这些迁移。该脚本会创建一个到 Neon 数据库的新连接，并执行 `drizzle` 目录中所有未执行的迁移。

```ts migrate.ts theme={"theme":{"light":"github-light","dark":"dracula"}}
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` 运行此脚本来执行迁移。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run migrate.ts
```

```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Migration completed
```

***

现在，我们可以为数据库添加一些数据。创建一个 `seed.ts` 文件，内容如下。

```ts seed.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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();
```

***

然后运行此文件。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run seed.ts
```

```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Seeding completed
```

***

现在我们已经有了带有架构和示例数据的数据库，可以使用 Drizzle 进行查询。将 `index.ts` 的内容替换为以下代码。

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
import * as schema from "./schema";
import { db } from "./db";

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

***

接着运行该文件。你应该看到我们插入的三位作者信息。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
```

```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
[
  {
    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 的无服务器驱动还提供 `Client` 和 `Pool` 构造器，以支持会话、交互式事务和兼容 node-postgres。详见 [Neon 文档](https://neon.tech/docs/serverless/serverless-driver) 获取完整介绍。

更多关于 Drizzle ORM 的使用文档，请参考 [Drizzle 官网](https://orm.drizzle.team/docs/overview)。
