encore-database

安装量: 145
排名: #5923

安装

npx skills add https://github.com/encoredev/skills --skill encore-database

Encore Database Operations Instructions Database Setup import { SQLDatabase } from "encore.dev/storage/sqldb";

const db = new SQLDatabase("mydb", { migrations: "./migrations", });

Query Methods

Encore provides three main query methods:

query - Multiple Rows

Returns an async iterator for multiple rows:

interface User { id: string; email: string; name: string; }

const rows = await db.querySELECT id, email, name FROM users WHERE active = true;

const users: User[] = []; for await (const row of rows) { users.push(row); }

queryRow - Single Row

Returns one row or null:

const user = await db.queryRowSELECT id, email, name FROM users WHERE id = ${userId};

if (!user) { throw APIError.notFound("user not found"); }

exec - No Return Value

For INSERT, UPDATE, DELETE operations:

await db.execINSERT INTO users (id, email, name) VALUES (${id}, ${email}, ${name});

await db.execUPDATE users SET name = ${newName} WHERE id = ${id};

await db.execDELETE FROM users WHERE id = ${id};

Migrations File Structure service/ └── migrations/ ├── 001_create_users.up.sql ├── 002_add_posts.up.sql └── 003_add_indexes.up.sql

Naming Convention Start with a number (001, 002, etc.) Followed by underscore and description End with .up.sql Numbers must be sequential Example Migration -- 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);

Drizzle ORM Integration Setup // db.ts import { SQLDatabase } from "encore.dev/storage/sqldb"; import { drizzle } from "drizzle-orm/node-postgres"; import * as schema from "./schema";

const db = new SQLDatabase("mydb", { migrations: { path: "migrations", source: "drizzle", }, });

export const orm = drizzle(db.connectionString, { schema });

Schema // schema.ts import * as p from "drizzle-orm/pg-core";

export const users = p.pgTable("users", { id: p.uuid().primaryKey().defaultRandom(), email: p.text().unique().notNull(), name: p.text().notNull(), createdAt: p.timestamp().defaultNow(), });

Drizzle Config // drizzle.config.ts import { defineConfig } from "drizzle-kit";

export default defineConfig({ out: "migrations", schema: "schema.ts", dialect: "postgresql", });

Generate migrations: drizzle-kit generate

Using Drizzle import { orm } from "./db"; import { users } from "./schema"; import { eq } from "drizzle-orm";

// Select const allUsers = await orm.select().from(users); const user = await orm.select().from(users).where(eq(users.id, id));

// Insert await orm.insert(users).values({ email, name });

// Update await orm.update(users).set({ name }).where(eq(users.id, id));

// Delete await orm.delete(users).where(eq(users.id, id));

SQL Injection Protection

Encore's template literals automatically escape values:

// SAFE - values are parameterized const email = "user@example.com"; await db.queryRowSELECT * FROM users WHERE email = ${email};

// WRONG - SQL injection risk await db.queryRow(SELECT * FROM users WHERE email = '${email}');

Guidelines Always use template literals for queries (automatic escaping) Specify types with generics: query, queryRow Migrations are applied automatically on startup Use queryRow when expecting 0 or 1 result Use query with async iteration for multiple rows Database names should be lowercase, descriptive Each service typically has its own database

返回排行榜