Open7

PGLite WASM試す。

knaka Tech-Blogknaka Tech-Blog

概要

  • PGLite (postgres) WASM 使うメモです。
  • node.js から操作する例

[ 公開 2025/08/17 ]


環境

  • PGLite PostgreSQL 17
  • @electric-sql/pglite
  • node 22

関連

https://pglite.dev

https://www.publickey1.jp/blog/25/postgresqlwebassemblypglitepostgresql_17.html


テスト用コード


  • install
npm install @electric-sql/pglite

  • test1.js
  • pgdata: データのフォルダ
import { PGlite } from '@electric-sql/pglite'

const db = new PGlite('./pgdata')
await db.exec(`
  CREATE TABLE IF NOT EXISTS todo (
    id SERIAL PRIMARY KEY,
    task TEXT,
    done BOOLEAN DEFAULT false
  );
  INSERT INTO todo (task, done) VALUES ('Install PGlite from NPM', true);
  INSERT INTO todo (task, done) VALUES ('Load PGlite', true);
  INSERT INTO todo (task, done) VALUES ('Create a table', true);
  INSERT INTO todo (task, done) VALUES ('Insert some data', true);
  INSERT INTO todo (task) VALUES ('Update a task');
`)

// SELECT
const ret = await db.query(`
  SELECT * from todo;
`)
console.log(ret.rows)

  • 実行すると。 db作成、table作成、レコード登録完了になります。

  • test2.js
  • SELECTの例
import { PGlite } from '@electric-sql/pglite'

const db = new PGlite('./pgdata')


// SELECT
const ret = await db.query(`
  SELECT * from todo;
`)
console.log(ret.rows)


感想

  • DBの設定作業が、ほとんど無く。ローカルのデータ保存方法としては。良さそうです
knaka Tech-Blogknaka Tech-Blog

drizzle-ORM , PGLite の例

  • drizzle使う例です。

環境

  • drizzle-ORM
  • PGLite PostgreSQL 17
  • @electric-sql/pglite
  • node 22

  • install
npm install -D drizzle-kit
npm install drizzle-orm drizzle-typebox

  • src/db.ts
import { PGlite } from "@electric-sql/pglite";
import { drizzle } from "drizzle-orm/pglite";

const client = await PGlite.create({
  dataDir: "pgdata",
});
export const db = drizzle(client);


  • src/schema.ts
import { pgTable, integer , serial, timestamp, varchar, text , boolean } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-typebox";

export const todo = pgTable("todo", {
  id: serial("id").primaryKey(),
  task: text("task").notNull(),
  done: boolean(),
  createdAt: timestamp("created_at").defaultNow(),
});

export const insertTodoSchema = createInsertSchema(todo);


  • drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./src/schema.ts",
  out: "./drizzle",
  dbCredentials: {
    url: "./pgdata",
  },
  driver: "pglite",
});



  • migration
npx drizzle-kit generate
npx drizzle-kit migrate

  • test_dr_1.ts , 書き込みテスト
import { eq } from "drizzle-orm";
import { db } from "./src/db";
import { todo } from "./src/schema";

export const createItem = async function(){
  const todoData = {
    task: "t1",
  }
  await db.insert(todo).values(todoData).returning();
};
export const listItem = () => {
  return db.select().from(todo);
};
const start = async function(){
  await createItem();
  const item = await listItem();
  console.log(item);
}

start();



  • 実行すると、登録できました。
npx tsx test_dr_1
knaka Tech-Blogknaka Tech-Blog

SQLite , PGLite WASM 比較

  • 主に、速度面の比較になります。

環境

  • PGLite PostgreSQL 17
  • @electric-sql/pglite
  • node 22
  • SQLite
  • drizzle-ORM

  • 速度結果: PGLite , SQLite-drizzle transactionなし
  • 測定方法: 1,000件 INSERT 時間測定
  • 数回測定し、平均値を計算する , 単位 msec
  • 複数件数の追加で、PGLite 速い (transaction無しの場合)
PGLite SQLite-drizzle
865 2319


テスト用コード


  • drizzle-orm transactionなし
import { drizzle } from 'drizzle-orm/libsql';
import { eq } from 'drizzle-orm';
import { todos } from './src/db/schema';
import 'dotenv/config'

(async () => {
  console.time('proc-time');
  const db = drizzle(process.env.DB_FILE_NAME);

  let targetNum = 1;
  for (let step = 0; step < 1000; step++) {
    targetNum = step + 1;
    let setValue = `title:${targetNum}`;
    let newItem = {
      title: setValue,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };
    const result = await db.insert(todos).values(newItem).returning();
  }
  console.timeEnd('proc-time');
})();

  • PGLite
  • test_time.js
import { PGlite } from '@electric-sql/pglite'
import 'dotenv/config'
console.log("DATA_DIR=", process.env.DATA_DIR)


const run = async function(){
  try{
    console.time('proc-time');
    const db = new PGlite(process.env.DATA_DIR)
    let targetNum = 1;
    for (let step = 0; step < 1000; step++) {
      targetNum = step + 1;
      let setValue = `k:${targetNum}`;
      let sql = `INSERT INTO todo 
      (title, content) VALUES ('${setValue}', 'c1');
      `;
        await db.exec(sql);
    }
    db.close();
    console.timeEnd('proc-time');
  }catch(e){
    console.error(e);
  }
}
run();


  • 考察
  • 調べると、drizzle-ormで 件数多い INSERT は、transactionなしで。遅延らしい

SQLite transaction 使用テスト , PGLite WASM

SQLite-transaction PGLite SQLite-drizzle
98 865 2319
  • 追加件数: 1,000件 (上記と同じ)
  • 単位 msec
  • SQLite-drizzle-transaction 速く、PGLite遅い。


  • SQLite-drizzle-transaction 計測
  • test_tran2.js
import { drizzle } from 'drizzle-orm/libsql';
import { int, sqliteTable, text, integer, primaryKey } from "drizzle-orm/sqlite-core";
import { sql } from 'drizzle-orm';
import { eq } from 'drizzle-orm';
//import { todos } from './src/db/schema';
import 'dotenv/config'

(async () => {
  console.time('proc-time');
  const db = drizzle(process.env.DB_FILE_NAME);
  const todos = sqliteTable('todo', {
    id: integer('id').primaryKey({ autoIncrement: true }),
    title: text('title').notNull(),
    created_at: text('created_at').notNull().default(new Date().toISOString()),
    updated_at: text('updated_at').notNull().default(new Date().toISOString())
  });

  let targetNum = 1;
  await db.transaction(async (tx) => {
    for (let step = 0; step < 1000; step++) {
      targetNum = step + 1;
      let setValue = `title:${targetNum}`;
      let newItem = {
        title: setValue,
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString(),
      };
      await tx.insert(todos).values(newItem);
    }
  });
  console.timeEnd('proc-time');
})();


考察

  • PGLite 更新系で、高速化方法は。よくわからず。でした

knaka Tech-Blogknaka Tech-Blog

PGLite , SQL 実行ツール作成

  • node版の SQLツール的な作成メモです
  • CLI版

環境

  • PGLite PostgreSQL 17.x
  • @electric-sql/pglite
  • node 22

書いたコード

https://github.com/kuc-arc-f/rolldown_2ex/tree/main/pglite-tool


  • 使用方法
npm run start

  • SQL 入力
  • 最後行に [1]入力、[改行キー]おす。
複数行 又は、1行テキストを入力してください。
単独行で「1」の後に改行を入力すると実行されます。
input:
SELECT COUNT(*) FROM todo;
1

  • Log
input:
SELECT COUNT(*) FROM todo;
1

--- receive Text ---
SELECT COUNT(*) FROM todo;
sql:
SELECT COUNT(*) FROM todo;
SELECT result:
[ { count: 13284 } ]

knaka Tech-Blogknaka Tech-Blog

PGLite WASM エクスポート ツール (export , import)

  • bunで、 PGLiteデータのエクスポート、インポート機能 試作です。
  • CLI版

環境

  • PGLite PostgreSQL 17.x
  • @electric-sql/pglite
  • bun 1.2.20

書いたコード

https://github.com/kuc-arc-f/bun_41ex/tree/main/pglite-dump


  • env
DATA_DIR="/path/pgdata"

export

  • table

CREATE TABLE IF NOT EXISTS item (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title TEXT,
  content TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);


  • データ追加
  • export
bun run export.ts

  • 出力する table_name を。入力します
>bun run export.ts
DATA_DIR= /tmp/pgdata
table_name:


  • dump.sql 出力
INSERT INTO "item" (id ,title ,content ,created_at ,updated_at ) VALUES ('6e949e5d-42c6-4771-b2e7-288738cfca00', 't1', NULL, '2025-08-30T03:52:18.006000', '2025-08-30T03:52:18.006000');
INSERT INTO "item" (id ,title ,content ,created_at ,updated_at ) VALUES ('f3edfa96-a17b-4728-9bee-64739e8cfaa1', 't3', NULL, '2025-08-30T03:52:18.006000', '2025-08-30T03:52:18.006000');
INSERT INTO "item" (id ,title ,content ,created_at ,updated_at ) VALUES ('a38a4c1d-e8ab-4198-835f-24af4d9e95be', 't4', NULL, '2025-08-30T03:52:18.006000', '2025-08-30T03:52:18.006000');
INSERT INTO "item" (id ,title ,content ,created_at ,updated_at ) VALUES ('24703c45-ff7d-451d-b469-401f0d222a2b', 't5', NULL, '2025-08-30T03:52:18.006000', '2025-08-30T03:52:18.006000');


import

  • drop TABLE
DROP TABLE item;

  • CREATE TABLE
  • 上記の、テーブルSQL実行

  • import: dump.sql 取り込み。
bun run import.ts

knaka Tech-Blogknaka Tech-Blog

テーブル一覧 追加 , PGLite WASM

  • テーブル一覧
  • public スキーマ

環境

  • PGLite PostgreSQL 17.x
  • @electric-sql/pglite
  • bun 1.2.20

書いたコード

https://github.com/kuc-arc-f/bun_41ex/tree/main/pglite-tool


  • テーブル一覧, 実行
bun run list

  • 出力
bun run list
DATA_DIR= /tmp/pgdata
VER= 0.9.1
[
  {
    tablename: "repo",
  }, {
    tablename: "repo_count",
  }, {
    tablename: "item",
  }, {
    tablename: "todo",
  }, {
    tablename: "plan",
  }, {
    tablename: "task",
  }
]