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

# 使用 Gel 与 Bun

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

***

首先，如果你还没有安装，请[安装 Gel](https://docs.geldata.com/learn/installation)。

<CodeGroup>
  ```sh Linux/macOS terminal icon="terminal" theme={null}
  curl https://www.geldata.com/sh --proto "=https" -sSf1 | sh
  ```

  ```sh Windows terminal icon="windows" theme={null}
  irm https://www.geldata.com/ps1 | iex
  ```

  ```sh Homebrew terminal icon="terminal" theme={null}
  brew install geldata/tap/gel-cli
  ```
</CodeGroup>

***

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

```sh terminal icon="terminal" theme={null}
mkdir my-edgedb-app
cd my-edgedb-app
bun init -y
```

***

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

```sh terminal icon="terminal" theme={null}
gel project init
```

```txt theme={null}
在 `/Users/colinmcd94/Documents/bun/fun/examples/my-gel-app` 或之上未找到 `gel.toml`
是否要初始化一个新项目？[Y/n]
> Y
指定与此项目一起使用的 Gel 实例名称 [default: my_gel_app]：
> my_gel_app
检查 Gel 版本...
指定与此项目一起使用的 Gel 版本 [default: x.y]：
> x.y
┌─────────────────────┬──────────────────────────────────────────────────────────────────┐
│ 项目目录             │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app         │
│ 项目配置             │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/gel.toml│
│ 模式目录（空）         │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema│
│ 安装方式             │ 便携式包                                                         │
│ 版本                 │ x.y+6d5921b                                                      │
│ 实例名称             │ my_gel_app                                                       │
└─────────────────────┴──────────────────────────────────────────────────────────────────┘
版本 x.y+6d5921b 已下载
正在初始化 Gel 实例...
正在应用迁移...
一切已是最新。修订版 initial
项目初始化完成。
要连接到 my_gel_app，运行 `gel`
```

***

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

```sh terminal icon="terminal" theme={null}
gel
gel> select 1 + 1；
```

```txt theme={null}
2
```

然后运行 `\quit` 退出 REPL。

```sh terminal icon="terminal" theme={null}
gel> \quit
```

***

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

```txt 文件树 icon="folder-tree" theme={null}
dbschema
├── default.esdl
└── migrations
```

***

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

```ts default.esdl icon="file-code" theme={null}
module default {
  type Movie {
    required title: str;
    releaseYear: int64；
  }
}；
```

***

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

```sh terminal icon="terminal" theme={null}
gel migration create
```

```txt theme={null}
已创建 /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema/migrations/00001.edgeql，id: m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq
```

```sh terminal icon="terminal" theme={null}
gel migrate
```

```txt theme={null}
已应用 m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq (00001.edgeql)
```

***

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

```sh terminal icon="terminal" theme={null}
bun add gel
bun add -D @gel/generate
touch seed.ts
```

***

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

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

```ts seed.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
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 运行此文件。

```sh terminal icon="terminal" theme={null}
bun run seed.ts
```

```txt theme={null}
种子数据完成。
```

***

Gel 实现了多个 TypeScript 代码生成工具。要对已填充数据的数据库编写类型安全查询，用 `@gel/generate` 生成 EdgeQL 查询构建器。

```sh terminal icon="terminal" theme={null}
bunx @gel/generate edgeql-js
```

```txt theme={null}
正在生成查询构建器...
检测到 tsconfig.json，正在生成 TypeScript 文件。
   要覆盖此设置，请使用 --target 标志。
   运行 `npx @edgedb/generate --help` 查看完整选项。
正在自省数据库模式...
正在将文件写入 ./dbschema/edgeql-js
生成完成！🤘
不建议将生成的查询构建器检查到版本控制中。
是否要更新 .gitignore 以忽略查询构建器目录？将添加以下行：

   dbschema/edgeql-js

[y/n]（留空表示 "y"）
> y
```

***

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

```ts index.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
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 运行该文件以查看你插入的电影。

```sh terminal icon="terminal" theme={null}
bun run index.ts
```

```txt theme={null}
[
  {
    title: "The Matrix",
    releaseYear: 1999
  }, {
    title: "The Matrix Reloaded",
    releaseYear: 2003
  }, {
    title: "The Matrix Revolutions",
    releaseYear: 2003
  }
]
```

***

参见 [Gel 文档](https://docs.geldata.com/)。
