Watch the synthetic workflow
This recording uses made-up inputs in the offline product. It shows the supported steps; it is not a customer result. Captions describe the steps; there is no audio.
What you are looking at
A consultant inspects the SQL, opens the HTML handoff, writes a note the client can read, saves a copy, and checks the CSV list of tables and columns. This example does that walk once, with a fake shop schema of 12 tables, 54 columns, and 15 relationships. Those counts come from running the accepted SchemaHand engine on the file in this folder named source.sql. They are not estimates.
The saved HTML lets you edit notes and use Save edited copy. That new HTML keeps the notes. It does not change the separate CSV file.
Handoff walkthrough
- Inspect the SQL. Open source.sql and confirm it is table definitions, not rows of people.
- Open the rendered handoff. Use handoff.html. Check tables, columns, and relationship lines.
- Add a client-facing note on app.customers. A synthetic note is already in this copy so you can see where it lives.
- Click Save edited copy, then reopen the downloaded HTML. The note should still be there. Table names should be unchanged.
- Inspect the dictionary. Open dictionary.csv and find addresses.customer_id linking to app.customers(id). Same relationship as the HTML. The CSV does not pick up the HTML note.
Short practitioner lesson Demonstration script for a person to read
The demonstration script is a shot list. A recording of the synthetic workflow appears below.
Supported input for this product
SchemaHand reads a CREATE TABLE script. PostgreSQL and MySQL table definitions are the supported shape. This example file is PostgreSQL-flavored. The engine keeps:
- CREATE TABLE, including quoted names and schema prefixes such as app.customers
- Column types, NULL / NOT NULL, defaults, PRIMARY KEY, UNIQUE, and inline REFERENCES
- Table-level FOREIGN KEY and ALTER TABLE ... ADD FOREIGN KEY
- COMMENT ON TABLE and COMMENT ON COLUMN
It does not connect to a database, migrate data, or run SELECT. It does not claim every SQL dialect. CHECK clauses and CREATE INDEX are not turned into relationships. CREATE SCHEMA is not turned into a table.
Exact input (synthetic)
Full file: source.sql. Opening lines:
-- Synthetic PostgreSQL schema for testing the schemahand parser.
-- 12 tables, 15 foreign keys, 2 schemas (app, audit), table + column comments.
-- Every value below is made up. No real business appears here.
CREATE SCHEMA app;
CREATE SCHEMA audit;
CREATE TABLE app.customers (
id INTEGER PRIMARY KEY,
"full_name" VARCHAR(120) NOT NULL,
email TEXT UNIQUE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now()
);
COMMENT ON TABLE app.customers IS 'People and companies who buy from us.';
COMMENT ON COLUMN app.customers.email IS 'Unique email address used for login.';
CREATE TABLE app.addresses (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES app.customers(id),
line1 VARCHAR(200) NOT NULL,
city VARCHAR(80) NOT NULL,
postal_code VARCHAR(20)
);
CREATE TABLE app.categories (
id INTEGER PRIMARY KEY,
name VARCHAR(80) NOT NULL,
parent_category_id INTEGER,
CONSTRAINT fk_categories_parent FOREIGN KEY (parent_category_id)
REFERENCES app.categories (id)
);
CREATE TABLE app.suppliers (
id INTEGER PRIMARY KEY,
name VARCHAR(120) NOT NULL,
active BOOLEAN NOT NULL DEFAULT true
);
Exact output counts
From the accepted engine on that file: 12 tables, 54 columns, 15 relationships, 3 unused statements.
Tables and columns
| Table | Columns | Column names |
|---|---|---|
| app.customers | 5 | id, full_name, email, status, created_at |
| app.addresses | 5 | id, customer_id, line1, city, postal_code |
| app.categories | 3 | id, name, parent_category_id |
| app.suppliers | 3 | id, name, active |
| app.products | 6 | id, sku, name, price, category_id, supplier_id |
| app.orders | 6 | id, customer_id, billing_address_id, shipping_address_id, order_date, total_amount |
| app.order_items | 4 | order_id, product_id, quantity, unit_price |
| app.payments | 5 | id, order_id, amount, method, paid_at |
| app.invoices | 5 | id, order_id, customer_id, issued_at, total_amount |
| app.inventory | 4 | id, product_id, warehouse, quantity_on_hand |
| audit.login_events | 4 | id, customer_id, user_agent, happened_at |
| audit.change_log | 4 | id, customer_id, table_name, changed_at |
Relationships
Each row is one foreign key the engine kept. The same keys appear in dictionary.csv and in handoff.html.
| From | To |
|---|---|
| app.invoices (order_id) | app.orders(id) |
| app.invoices (customer_id) | app.customers(id) |
| audit.login_events (customer_id) | app.customers(id) |
| audit.change_log (customer_id) | app.customers(id) |
| app.addresses (customer_id) | app.customers(id) |
| app.categories (parent_category_id) | app.categories(id) |
| app.products (supplier_id) | app.suppliers(id) |
| app.products (category_id) | app.categories(id) |
| app.orders (billing_address_id) | app.addresses(id) |
| app.orders (shipping_address_id) | app.addresses(id) |
| app.orders (customer_id) | app.customers(id) |
| app.order_items (product_id) | app.products(id) |
| app.order_items (order_id) | app.orders(id) |
| app.payments (order_id) | app.orders(id) |
| app.inventory (product_id) | app.products(id) |
CSV dictionary excerpt
schema,table,column,type,primary_key,foreign_key,not_null,default,notes
app,customers,id,INTEGER,yes,,yes,,
app,customers,full_name,VARCHAR(120),,,yes,,
app,customers,email,TEXT,,,yes,,Unique email address used for login.
app,customers,status,VARCHAR(20),,,yes,active,
app,customers,created_at,TIMESTAMP WITHOUT TIME ZONE,,,yes,now(),
app,addresses,id,INTEGER,yes,,yes,,
app,addresses,customer_id,INTEGER,,app.customers(id),yes,,
app,addresses,line1,VARCHAR(200),,,yes,,Unused statements in this file
3 statement(s) were not used as tables or relationships. This edition reads CREATE TABLE, ALTER TABLE foreign keys, and COMMENT ON. Other statements are not treated as understood relationships.
CREATE SCHEMA appCREATE SCHEMA auditCREATE INDEX idx_orders_customer ON app.orders (customer_id)
Limits
- This static sample cannot process buyer input. There is no upload and no paste box on this page.
- No database connection, no data migration, and no query execution.
- Not universal SQL support.
- No GDPR or compliance promise.
- The free zip is this fixed example only, not a general parser.
- Notes edited in the saved HTML do not update the separate CSV.
- No paid key is included or required to inspect this example.
Download the example
The zip holds source.sql, handoff.html, dictionary.csv, a README that repeats the synthetic label and the limits, and a SHA-256 list for those files.
Example source
Synthetic input and product output generated and checked on 2026-09-20. The source files and output files are provided above. The linked Gumroad price was checked on the same date. No customer records were used.