Features
Databases
Add SQLite databases to your workers with Cloudflare D1-compatible API.
Databases
Ploy supports SQLite databases using a Cloudflare D1-compatible API. Each project gets its own isolated database that persists across deployments.
Configuration
Add a database binding in your ploy.yaml:
kind: dynamic
build: pnpm build
out: dist
db:
DB: defaultThe key (DB) is the binding name available in your worker's env. The value (default) is the database identifier.
Run ploy types to generate TypeScript types:
import type { Database } from "@meetploy/types";
export interface Env {
DB: Database;
}Basic Example
export default {
async fetch(request, env) {
// Create table
await env.DB.exec(
`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)`,
);
// Insert
await env.DB.prepare("INSERT INTO users (name) VALUES (?)")
.bind("Alice")
.run();
// Query
const { results } = await env.DB.prepare("SELECT * FROM users").all();
return Response.json({ users: results });
},
} satisfies Ploy;Query Methods
all() - Get All Rows
const { results } = await env.DB.prepare("SELECT * FROM users").all();first() - Get First Row
const user = await env.DB.prepare("SELECT * FROM users WHERE id = ?")
.bind(1)
.first();run() - Execute Statement
const result = await env.DB.prepare("INSERT INTO users (name) VALUES (?)")
.bind("Bob")
.run();
console.log(result.meta.rows_written); // 1exec() - Run Raw SQL
await env.DB.exec(`
CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY, title TEXT);
CREATE INDEX IF NOT EXISTS idx_title ON posts(title);
`);TypeScript Support
Add generics for type-safe queries:
interface User {
id: number;
name: string;
}
const users = await env.DB.prepare("SELECT * FROM users").all<User>();
// users.results is User[]
const user = await env.DB.prepare("SELECT * FROM users WHERE id = ?")
.bind(1)
.first<User>();
// user is User | nullAlways use prepared statements with .bind() to prevent SQL injection.
Next Steps
How is this guide?
Last updated on