Guide for writing SELECT, INSERT, UPDATE, DELETE queries with workers-qb
Use this skill when:
| Database | Class | Sync/Async | Import |
|---|---|---|---|
| Cloudflare D1 | D1QB | async | import { D1QB } from 'workers-qb' |
| Durable Objects | DOQB | sync | import { DOQB } from 'workers-qb' |
| PostgreSQL | PGQB |
import { PGQB } from 'workers-qb' |
// D1QB/PGQB - ALWAYS use await
const result = await qb.fetchAll({ tableName: 'users' }).execute();
// DOQB - NEVER use await (synchronous)
const result = qb.fetchAll({ tableName: 'users' }).execute();
DOQB is synchronous. This is the most common mistake. Inside Durable Objects:
// CORRECT
const users = qb.fetchAll({ tableName: 'users' }).execute();
// WRONG - don't await DOQB
const users = await qb.fetchAll({ tableName: 'users' }).execute();
Define a schema type for autocomplete and type safety:
type Schema = {
users: {
id: number;
name: string;
email: string;
created_at: string;
};
posts: {
id: number;
user_id: number;
title: string;
content: string;
};
};
const qb = new D1QB<Schema>(env.DB);
// Now tableName, fields, returning all have autocomplete
// Fetch all rows
const users = await qb.fetchAll({
tableName: 'users',
}).execute();
// Fetch one row
const user = await qb.fetchOne({
tableName: 'users',
where: {
conditions: 'id = ?',
params: [1],
},
}).execute();
// Select specific fields
const emails = await qb.fetchAll({
tableName: 'users',
fields: ['id', 'email'],
}).execute();
// Basic chain
const users = await qb.select('users')
.where('is_active = ?', true)
.orderBy({ name: 'ASC' })
.limit(10)
.all();
// Single row
const user = await qb.select('users')
.where('id = ?', userId)
.one();
// Count query
const count = await qb.select('users')
.where('is_active = ?', true)
.count();
console.log(count.results?.total);
// Single condition