執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

使用 Drizzle ORM 連線 Neon Postgres

Neon 是一款完全託管的無伺服器 Postgres。Neon 將計算與儲存分離,從而提供自動擴縮、分支和無限儲存等功能。你可以通過 @neondatabase/serverless 驅動直接在 Bun 中使用 Neon,也可以通過 Drizzle 這樣的 ORM 使用 Neon。

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://username:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require

在 db.ts 中,使用 Neon 無伺服器驅動連線到 Neon 資料庫,並將其包裝在 Drizzle 資料庫例項中。

db.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

// Bun 會自動從 .env.local 載入 DATABASE_URL
// 參考:https://bun.sh/docs/runtime/environment-variables 獲取更多資訊
const sql = neon(process.env.DATABASE_URL!);

export const db = drizzle({ client: sql });

為了演示資料庫的使用,在 index.ts 中新增以下程式碼。

index.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
[
  {
    text: "hello world",
  }
]

使用 Drizzle ORM 的基礎元件為資料庫定義架構。建立一個 schema.ts 檔案,並新增以下程式碼。

schema.ts
import { pgTable, integer, serial, text, timestamp } from "drizzle-orm/pg-core";

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

然後使用 drizzle-kit CLI 生成初始 SQL 遷移。

shell
bunx drizzle-kit generate --dialect postgresql --schema ./schema.ts --out ./drizzle

該命令會建立一個 drizzle 目錄,其中包含一個 .sql 遷移檔案和一個 meta 目錄。

檔案樹
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
Text
Migration completed

現在向資料庫中新增一些資料。建立一個 seed.ts 檔案,並新增以下內容。

seed.ts
import { db } from "./db";
import * as schema from "./schema";

async function seed() {
  await db.insert(schema.authors).values([
    {
      name: "J.R.R. Tolkien",
      bio: "The creator of Middle-earth and author of The Lord of the Rings.",
    },
    {
      name: "George R.R. Martin",
      bio: "The author of the epic fantasy series A Song of Ice and Fire.",
    },
    {
      name: "J.K. Rowling",
      bio: "The creator of the Harry Potter series.",
    },
  ]);
}

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
Text
Seeding completed

資料庫現在已經擁有架構和範例資料。將 index.ts 的內容替換為以下程式碼,即可使用 Drizzle 查詢資料庫。

index.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
Text
[
  {
    id: 1,
    name: "J.R.R. Tolkien",
    bio: "The creator of Middle-earth and author of The Lord of the Rings.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 2,
    name: "George R.R. Martin",
    bio: "The author of the epic fantasy series A Song of Ice and Fire.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 3,
    name: "J.K. Rowling",
    bio: "The creator of the Harry Potter series.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }
]

此範例使用了 Neon 無伺服器驅動的 SQL-over-HTTP 功能。Neon 的無伺服器驅動還提供了 Client 和 Pool 建構函式,以支援會話、互動式事務和 node-postgres 相容性。請參閱 Neon 的文件 瞭解完整概覽。

請參閱 Drizzle 網站 獲取完整文件。