运行时包管理器打包器测试运行器代码检查格式化指南参考博客反馈

在 Bun 中使用 Gel

Gel(前身为 EdgeDB)是一个构建于 Postgres 之上的图关系型数据库。它提供声明式模式语言、迁移系统和面向对象的查询语言。它也支持原始 SQL 查询。它在数据库层解决了对象关系映射问题,因此你的应用程序代码无需使用 ORM 库。


首先,如果你还没有安装,请安装 Gel。

Linux/macOS
curl https://www.geldata.com/sh --proto "=https" -sSf1 | sh
Windows
irm https://www.geldata.com/ps1 | iex
Homebrew
brew install geldata/tap/gel-cli

使用 bun init 创建一个新的项目。

terminal
mkdir my-gel-app
cd my-gel-app
bun init -y

使用 Gel CLI 为项目初始化一个 Gel 实例。gel project init 命令会在项目根目录中创建一个 gel.toml 文件。

terminal
gel project init
Text
No `gel.toml` (or `edgedb.toml`) found in `/Users/colinmcd94/Documents/bun/fun/examples/my-gel-app` or above
Initializing new project...
Checking Gel versions...
┌─────────────────────┬──────────────────────────────────────────────────────────────────┐
│ Project directory   │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app          │
│ Project config      │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/gel.toml │
│ Schema dir (empty)  │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema │
│ Installation method │ portable package                                                 │
│ Version             │ x.y+6d5921b                                                      │
│ Instance name       │ my_gel_app                                                       │
│ Branch              │ main                                                             │
└─────────────────────┴──────────────────────────────────────────────────────────────────┘
Version x.y+6d5921b is already downloaded
Initializing Gel instance 'my_gel_app'...
Applying migrations...
Everything is up to date. Revision initial
Writing gel.local.toml for configuration
Project initialized.
To connect to my_gel_app, run `gel`

要检查数据库是否正在运行,请打开 REPL 并运行一个查询。

terminal
gel
my_gel_app:main> select 1 + 1;
Text
{2}

然后运行 \quit 退出 REPL。

terminal
my_gel_app:main> \quit

接下来,定义一个模式。gel project init 命令已经创建了一个 dbschema/default.gel 文件来保存它。

File
dbschema
├── default.gel
├── extensions.gel
├── futures.gel
└── migrations

打开该文件,粘贴以下内容。

default.gel
module default {
  type Movie {
    required title: str;
    releaseYear: int64;
  }
};

然后生成并应用一个初始迁移。

terminal
gel migration create
Text
Created dbschema/migrations/00001-m1uwekr.edgeql, id: m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq
terminal
gel migrate
Text
Applying m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq (00001-m1uwekr.edgeql)
... parsed
... applied

应用模式后,使用 Gel 的 JavaScript 客户端库查询数据库。安装客户端库和 Gel 的代码生成 CLI,然后创建一个 seed.ts 文件。

terminal
bun add gel
bun add -D @gel/generate
touch seed.ts

将以下代码粘贴到 seed.ts。

客户端会自动连接到数据库。该脚本使用 .execute() 方法插入几部电影,并使用 EdgeQL 的 for 表达式将批量插入转换为单个查询。

seed.ts
import { createClient } from "gel";

const client = createClient();

const INSERT_MOVIE = `
  with movies := <array<tuple<title: str, year: int64>>>$movies
  for movie in array_unpack(movies) union (
    insert Movie {
      title := movie.title,
      releaseYear := movie.year,
    }
  )
`;

const movies = [
  { title: "The Matrix", year: 1999 },
  { title: "The Matrix Reloaded", year: 2003 },
  { title: "The Matrix Revolutions", year: 2003 },
];

await client.execute(INSERT_MOVIE, { movies });

console.log(`种子数据插入完成。`);
process.exit();

然后使用 Bun 运行此文件。

terminal
bun run seed.ts
Text
种子数据插入完成。

Gel 为 TypeScript 提供了多个代码生成工具。要针对已填充种子数据的数据库编写类型安全的查询,请使用 @gel/generate 生成 EdgeQL 查询构建器。

terminal
bunx @gel/generate edgeql-js
Text
Generating query builder...
Detected tsconfig.json, generating TypeScript files.
   To override this, use the --target flag.
   Run `npx @gel/generate --help` for full options.
Introspecting database schema...
Writing files to ./dbschema/edgeql-js
Generation complete! 🤘
Checking the generated query builder into version control
is not recommended. Would you like to update .gitignore to ignore
the query builder directory? The following line will be added:

   dbschema/edgeql-js

[y/n](留空为"y")
> y

在 index.ts 中,从 ./dbschema/edgeql-js 导入生成的查询构建器,并编写一个选择查询。

index.ts
import { createClient } from "gel";
import e from "./dbschema/edgeql-js";

const client = createClient();

const query = e.select(e.Movie, () => ({
  title: true,
  releaseYear: true,
}));

const results = await query.run(client);
console.log(results);

results; // { title: string, releaseYear: number | null }[]

使用 Bun 运行该文件,查看刚才插入的电影。

terminal
bun run index.ts
Text
[
  {
    title: "The Matrix",
    releaseYear: 1999,
  }, {
    title: "The Matrix Reloaded",
    releaseYear: 2003,
  }, {
    title: "The Matrix Revolutions",
    releaseYear: 2003,
  }
]

请参阅 Gel 文档。