Visual PostgreSQL studio
Draw the schema.Ship the migration.
DataForge turns tables and relationships drawn on a canvas into reviewed, transactional SQL, then lets you query, explain and edit the result against a real PostgreSQL database.
The demo gives you a private copy of an e-commerce database. Break anything; it is yours alone.
- Database
- PostgreSQL 17, real and private
- Demo data
- 6 tables · 17,000+ rows
- Migrations
- One transaction per apply
- Queries
- Read-only unless you say so
Workflow
From canvas to commit, every step shows its SQL.
The draft is diffed against the live catalog by object identity, so a renamed column is a rename, not a drop and an add.
01 Design
Add tables, set types, keys, defaults and identity columns. Drag a column onto another table's key to create a foreign key. Invalid references are flagged before any SQL exists.
- reviews.product_id → products.id
- ON DELETE CASCADE
- rating smallint NOT NULL DEFAULT 5
02 Review the generated SQL
-- Create table public.reviews with 4 columns CREATE TABLE public.reviews ( id bigint GENERATED ALWAYS AS IDENTITY NOT NULL, product_id bigint NOT NULL, rating smallint NOT NULL DEFAULT 5, body text, CONSTRAINT reviews_pkey PRIMARY KEY (id) ); -- Link public.reviews to public.products ALTER TABLE public.reviews ADD CONSTRAINT reviews_product_id_fkey FOREIGN KEY (product_id) REFERENCES public.products (id) ON DELETE CASCADE;03 Apply, then query
- BEGIN
- pg_current_xact_id() → 1042
- step 1 of 2 · CREATE TABLE
- step 2 of 2 · ADD CONSTRAINT
- COMMIT
- status → applied
A migration is marked applied only after COMMIT returns. If the app stops mid-apply, the recorded transaction id settles the outcome with pg_xact_status().
Under the hood
The database enforces the rules. The interface only explains them.
- Read-only by role
- Reads run as a role that only has SELECT, inside READ ONLY transactions. Nobody guesses from the SQL text.
- One statement per message
- User SQL goes through the extended query protocol, which refuses multi-statement strings.
- A watchdog, not a hope
- statement_timeout first; then the server cancels and terminates the backend itself.
- Clean connections
- DISCARD ALL before a connection returns to the pool. No SET or temp table leaks into the next run.
- Private sandboxes
- Each project gets its own database and roles, with CONNECT revoked from everyone else.
- Sealed credentials
- AES-256-GCM with the connection id as associated data. Passwords never reach the browser.
- Exact diffs
- Tables and columns are identified by OID and attnum, so renames are detected, not guessed.
- Streaming I/O
- CSV imports and exports stream through cursors and batched unnest() inserts with savepoints.
- App
- Next.js 16 · React 19 · TypeScript
- Database
- PostgreSQL 17 · node-postgres · pg-cursor
- Interface
- React Flow · Monaco · TanStack Table
- Runtime
- Docker Compose · isolated networks
Try it
A real database is one click away.
- A private copy of an e-commerce database, created in under a second
- Six saved example queries, from window functions to JSONB
- Write mode, migrations and imports all work against your copy
- Removed automatically after a day