by @encoredev
Database queries, migrations, and ORM integration with Encore.ts.
import { SQLDatabase } from "encore.dev/storage/sqldb";
const db = new SQLDatabase("mydb", {
migrations: "./migrations",
});
Encore provides three main query methods:
query - Multiple RowsReturns an async iterator for multiple rows:
interface User {
id: string;
email: string;
name: string;
}
const rows = await db.query<User>`
SELECT id, email, name FROM users WHERE active = true
`;
const users: User[] = [];
for await (const row of rows) {
users.push(row);
}
queryRow - Single RowReturns one row or null:
const user = await db.queryRow<User>`
SELECT id, email, name FROM users WHERE id = ${userId}
`;
if (!user) {
throw APIError.notFound("user not found");
}
exec - No Return ValueFor INSERT, UPDATE, DELETE operations:
await db.exec`
INSERT INTO users (id, email, name)
VALUES (${id}, ${email}, ${name})
`;
await db.exec`
UPDATE users SET name = ${newName} WHERE id = ${id}
`;
await db.exec`
DELETE FROM users WHERE id = ${id}
`;
service/
└── migrations/
├── 001_create_users.up.sql
├── 002_add_posts.up.sql
└── 003_add_indexes.up.sql
.up.sql-- migrations/001_create_users.up.sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
// db.ts
import { SQLDatabase } from "encore.dev/storage/sqldb";
import { drizzle } from "drizzle-orm/node-postgres";
import * as schema from "./schema";
const db = new SQLD...