BunのビルトインSQLクライアントを使ってAurora PostgreSQLに接続する

BunのビルトインSQLクライアントを使ってAurora PostgreSQLに接続する

Clock Icon2025.01.28

はじめに

JavaScriptランタイムの1つとして知られる Bun が、バージョン1.2よりSQLクライアントをビルトインするようになりました。
リリース時点ではPostgreSQLのみに対応していますが、将来的にMySQLもサポートする予定とのことです。

https://bun.sh/blog/bun-v1.2#postgres-support-with-bun-sql

この新しい Bun.sql を使ってAurora PostgreSQLに接続してみました。

Bunのインストール

公式の手順とおりに Bun をインストールしていきます。

# インストール
$ curl -fsSL https://bun.sh/install | bash

# Bunのバージョンを確認
$ bun --version
1.2.0

今回リリースされた 1.2.0 がインストールされていることを確認できました。

事前準備

Aurora PostgreSQLクラスターを作成しておきます。今回は本筋ではないので手順を省略しますが、バージョンは以下のとおりです。

testdb=> select * From version();
                                             version
-------------------------------------------------------------------------------------------------
 PostgreSQL 15.4 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 9.5.0, 64-bit
(1 row)

サンプルコード

Bun.sql ですが、人気ライブラリの Postgres.js にインスパイアされているとのことで、使い方はかなり似ています。

https://github.com/porsager/postgres

スクリプトを書く前に、まずは .env ファイルを作成します。
DBのホスト名、ポート番号、ユーザ名、パスワード、データベース名といった接続情報を記述します。

PGHOST=xxxxxxxxxx.cluster-yyyyyyyyyyyy.ap-northeast-1.rds.amazonaws.com
PGPORT=5432
PGUSERNAME=admin
PGPASSWORD=****************************
PGDATABASE=testdb

こちらは Bun のほうでよしなに読み取ってくれます。
あとはスクリプトを書いていくだけです。試しに、テーブル作成・バルクインサート・データ取得、を行うスクリプトを書いてみました。

import { sql } from "bun";

await sql`
  CREATE TABLE users (
    name VARCHAR(16),
    age SMALLINT
  )
`;

const newUsers = [
  { name: "Taro", age: 20, },
  { name: "Jiro", age: 30, },
  { name: "Saburo", age: 40, },
];

await sql`
  INSERT INTO users ${sql(newUsers)}
`;

const users = await sql`
  SELECT name, age
  FROM users
`;

console.log(users);

Postgres.js と同様にテンプレートリテラルを使ってSQLを記述するので、非常に直感的な書き方ができます。
上記のスクリプトを実行すると出力結果は以下のようになります。

$ bun index.ts
[
  {
    name: "Taro",
    age: 20,
  }, {
    name: "Jiro",
    age: 30,
  }, {
    name: "Saburo",
    age: 40,
  }, statement: undefined, command: "SELECT", count: 3
]

このように、Aurora PostgreSQLにも問題なく接続でき、データの操作ができました。

Postgres.js との速度比較

公式の発表では、 Bun.sqlPostgres.js よりも高速であるとのことです。早速試してみましょう。
なお、 Node.js のバージョンは v22.13.1 で、 Postgres.js のバージョンは 3.4.5 を使います。

前準備

最初に、10万件のダミーデータを作成しておきます。せっかくなので、 Bun.sql で実行してみます。

const newUsers = Array.from({ length: 100000 }, (_, i) => ({
  name: `User${i}`,
  age: Math.floor(Math.random() * 100),
}));

// トランザクションを開始
await sql.begin(async tx => {
  // 1000件ずつバルクインサート
  for (let i = 0; i < newUsers.length; i += 1000) {
    await tx`
      INSERT INTO users ${sql(newUsers.slice(i, i + 1000))}
    `;
  }
});

実行時間計測用スクリプト

このデータを取得する際の実行時間を計測、比較してみます。以下のようなスクリプトを用意しました。

import { sql } from "bun";

async function main() {
  try{
    const randomId = Math.floor(Math.random() * 100000);
    const result = await sql`
      SELECT name, age
      FROM users
      WHERE name = ${`User${randomId}`}
    `;

    console.log('Result:', result);
  } catch (error) {
    console.error('Error:', error);
  } finally {
    await sql.end();
  }
}

main().catch(console.error);

同様に、 Postgres.js を使ったスクリプトも用意しました。内容はほぼ同じです。こちらは Node.js で実行します。

const postgres = require('postgres');

async function main() {
  const sql = postgres({
    host: process.env.PGHOST,
    database: process.env.PGDATABASE,
    username: process.env.PGUSER,
    password: process.env.PGPASSWORD,
  });

  try {
    const randomId = Math.floor(Math.random() * 100000);

    const result = await sql`
      SELECT name, age
      FROM users
      WHERE name = ${`User${randomId}`}
    `;

    console.log('Result:', result);
  } catch (error) {
    console.error('Error:', error);
  } finally {
    await sql.end();
  }
}

main().catch(console.error);

結果

Bun.sql での実行時間は以下のとおりです。3回ほど実行し、その平均に当たる値を採用しました。

$ time bun bun-test.ts
real    0m0.076s
user    0m0.024s
sys     0m0.008s

次に、 Postgres.js での実行時間を計測してみます。

$ time node --env-file=.env postgresjs-test.js
real    0m0.106s
user    0m0.062s
sys     0m0.018s

単純なクエリのテストなのでこれだけで判断するのは難しいですが、 Bun.sql のほうが高速であることが確認できました。

おわりに

Bun.sql を使ってAurora PostgreSQLに接続してみました。これまでよりも若干高速な処理が可能になり、別途ライブラリを用意する必要もなくなったので便利になったかなと思います。とは言え、シンプルゆえに手が届きにくい部分もあるかもしれませんので、 Postgres.js のような既存ライブラリを使う必要が出てくる場面もまだまだありそうです。
現在も開発が進んでいる段階なので、今後のアップデートに期待です。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.