Your application's database

Aha! Builder

Every Aha! Builder application is backed by its own PostgreSQL database. Your application defines tables, queries and updates them through a type-safe ORM, and evolves its structure over time with migration files. Elle creates and changes this structure as you describe the data your application needs to store.

This reference documents how the database is accessed: the Drizzle ORM connection, query operators, and the rules for writing migrations. Read it to understand how your application's data is stored and changed, to review what Elle generated, or to ground an AI assistant in the specifics — reference this article with Elle or any LLM so it knows exactly how the database works in Aha! Builder.

Click any of the following links to skip ahead:

Overview

Drizzle ORM is used for database access.

The active database connection is imported from builder-core.

import { db } from '@aha-app/builder-core';
import { eq } from 'drizzle-orm';
import { customersTable } from './schema.ts';

...

const customers = await db.select().from(customersTable).where(eq(customersTable.name, 'Chris'));

Top

Migrations

SQL migration files live in db/migrations/ and are executed in sorted filename order. Each migration runs only once — the system tracks which files have been executed and skips them on subsequent runs.

Rules

  • Never edit an existing migration. Once a migration has been executed, its filename is recorded. Editing it will not cause it to re-run. If you need to change a table, create a new migration file.

  • Use sequential numbered prefixes for ordering: 001_create_users.sql, 002_add_email_to_users.sql, etc.

  • Do not use IF NOT EXISTS — migrations run exactly once, so existence checks are unnecessary.

Creating a new migration

To modify an existing table, create a new migration file with the next number:

db/migrations/003_add_role_to_users.sql:

ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'member';

What if I need to undo a change?

Create a new migration that reverses the change:

db/migrations/004_remove_role_from_users.sql:

ALTER TABLE users DROP COLUMN role;

Top

Aha! user ID columns must use TEXT

The auth_identifier column in the users table stores the Aha! platform user ID as TEXT. If you add additional columns that reference Aha! platform IDs, use TEXT as well.

The local users.id column is a normal SERIAL integer. Use integer for foreign keys that reference it.

Top

Build it with Elle

Describe the capability you want in plain language, and Elle, the Aha! Builder AI assistant, builds it into your application using the framework above.

New to this? Open Elle, ask what it can do, and try a capability in your application today.

Top

Feedback received!

Error submitting feedback, please try again later