Skip to content

Working with Data

Alchemify gives you full CRUD access to your database tables, right in the browser.

Click a table name in the sidebar to see its list view — a paginated table showing rows with their columns. The total row count is displayed in the header.

  • Click any row to open its detail view.
  • If you have insert permission, a New button appears in the top right.

Tables are paginated — by default you see 25 rows per page. A pagination bar below the table shows:

  • Row range — e.g., “Showing 1–25 of 142”
  • Page size selector — choose 10, 25, 50, or 100 rows per page
  • Prev / Next buttons — navigate between pages

Switching tables, searching, sorting, or changing page size all reset you to the first page.

Click any column header to sort the table by that column. Click again to reverse the direction, and a third time to clear the sort. A small arrow icon shows the current sort direction. Null values always sort last.

If the table has text columns, a search box appears in the card header. Type to filter rows — the search runs against all text columns and updates after a short delay. The search is case-insensitive and matches anywhere in the value (e.g., searching “al” matches “Alice” and “California”). The row count in the header updates to reflect the filtered results.

Above the table on most table list views, a row of filter chips appears for the columns the AI Builder marked as filterable. Each chip type matches the column it represents:

Column typeChip behavior
Foreign key (e.g., customer_id)Searchable picker of related records
Choice (status, priority, …)Multi-select of the configured options
BooleanYes / No / Any
Date / DatetimeFrom-and-to range pickers

Active filter values are written to the URL, so a filtered view is bookmarkable and shareable — opening the same link lands the next reader on the same rows. Filters compose with search and sort; the row count in the header always reflects the filtered result.

Some tables ship with a default filter pre-applied (for example, a tasks table that opens with status = “open”). Once you touch any chip, your selection wins and the default no longer applies — even if you clear all chips, the URL records “user has chosen to see everything.” A Clear all link appears next to the chips when at least one filter is active.

Filter chips only appear on table list views. Custom views (the ones you create through the AI Builder) don’t have them.

An Export button in the card header gives you two options:

  • Download CSV — saves the rows to a file named <table>-YYYY-MM-DD.csv.
  • Copy as CSV — copies the same content to your clipboard for pasting into a spreadsheet.

Exports reflect the current grid state: active search, filters, sort, and the columns currently visible in the table (not every column in the underlying schema). Foreign-key and choice columns export the label you see on screen, not the raw id or code.

For large result sets, Alchemify asks you to confirm at 10,000 rows and refuses outright above 50,000 rows — narrow your filters and try again.

Next to the Export button (on tables you can insert into), an Import button opens a CSV-import dialog. Drop a .csv file in or click to pick one, and Alchemify will:

  1. Match each CSV header to a table column automatically — exact, case-insensitive, and normalized matches (First Namefirst_name). Adjust any column whose mapping you don’t want.
  2. Show a 10-row preview with type-coercion errors flagged before any row is inserted.
  3. On confirm, append the rows to the current table in chunks, with a progress bar.

Import is admin-only and limited to 20 MB files / 50,000 rows — same limits as the AI Builder’s CSV flow. The button only appears on regular tables, not on custom views.

To create a new table from a CSV (the AI proposes the schema), use the AI Builder’s CSV import instead. The toolbar Import button is for appending into a table that already exists.

The detail view shows every field for a single record. Column names are converted to human-friendly labels — for example, created_at shows as “Created on” and id shows as “ID”. Foreign-key columns drop the trailing _id from their header (so customer_id shows as “Customer”). The displayed value is the linked record’s label — resolved from the target table’s display columns (e.g., a customer’s name, not the raw ID) — and clicks through to that record. Empty values render as .

Values with a display type are formatted automatically: email addresses become clickable mailto: links, URLs become external links, colors show a swatch, currencies show $ formatting, percentages show %, ratings show filled stars, and booleans show a green checkmark or gray X icon. Boolean columns are detected automatically from the database type — no manual configuration needed. The same formatting applies in the list view.

Actions available (based on your permissions):

  • Edit — opens the edit form pre-filled with the current values
  • Delete — shows a confirmation dialog, then removes the record
  • Back to list — returns to the list view

Below the field/value section, the detail page lists the base tables that reference this record via a foreign key. For example, a customer’s detail page shows an embedded list of that customer’s orders, and an order’s detail page shows its line items.

Each related list is a compact list view scoped to the children of the current record. Clicking a row opens that child’s detail page, where you can drill further. Custom views are not embedded — only base tables (and their auto-generated _v views) appear here.

The platform tables users and files don’t show embedded lists on their detail pages. Many app tables reference users (audit columns, FKs to authors/owners) and files (upload columns), and showing every reference would crowd those pages with noise.

Click New on the list view to open the create form. Fields are generated automatically from the table’s columns:

  • Text fields (text, email, url, phone, color) → text input
  • Multiline fields → textarea
  • Numbers (integer, currency, percent, rating) → number input
  • Required booleans → Yes/No radio buttons
  • Optional booleans → checkbox
  • Date fields → date picker
  • Datetime fields → datetime picker

Auto-generated columns (like UUIDs, created_at, updated_at, updated_by) are skipped — the database fills those in. Required fields are marked with a red asterisk.

When the AI Builder creates or alters a table, it can assign a display type to columns (e.g., “add an email column”). Alchemify uses this to show smarter input widgets:

Display typeWidget
EmailEmail input with browser validation
URLURL input
PhoneTelephone input
ColorNative color picker
MultilineTextarea (regardless of column length)
CurrencyNumber input with $ prefix
PercentNumber input with % suffix
RatingClickable 1–5 star picker
Date / DatetimeDate or datetime picker

Tables without display types work exactly as before — widgets fall back to the column’s data type.

Columns with the file type show a file upload widget instead of a text input. When you ask the AI for a file upload field (e.g., “add a photo column”), it uses the file type automatically. You can:

  • Click or drag to upload a file
  • Download an uploaded file
  • Replace a file with a new upload (click the upload icon)
  • Clear the field (if the column is optional)

The file is uploaded immediately when selected — the returned file ID is stored in the form. Files are managed through the /view/files page, which shows all your uploaded files with download and delete actions.

Choice columns (status, priority, category, and so on) are dropdowns whose values are defined when the column is created. The AI Builder picks the options and their colors at creation time and you can edit them later — see Using the AI Builder.

  • In forms — a dropdown of the option labels, listed in the order configured by the builder (not alphabetical).
  • In list and detail views — a colored badge using the option’s configured color. Options without a color render as a plain badge.
  • Sorting by a choice column — sort follows the configured option order, so “open → in progress → done” stays in that order rather than going alphabetical.
  • Validation — the database itself enforces the option set, so a value outside the declared options is rejected no matter how it’s entered. A stale option can’t sneak in via a form, an AI proposal, or an import.

When you submit a form, Alchemify validates each field. If the column has a display type, semantic validation runs first:

Display typeRule
EmailMust be a valid email address
URLMust be a valid URL
PhoneDigits, spaces, parentheses, and hyphens only
ColorMust be a hex color (#rrggbb)
PercentMust be 0–100
RatingMust be 1–5

Otherwise, validation falls back to the column’s data type:

Column typeRule
Integer fieldsMust be a whole number
Numeric fieldsMust be a valid number
UUID fieldsMust match UUID format (e.g. 550e8400-e29b-41d4-a716-446655440000)
JSON fieldsMust be valid JSON
Required fieldsCannot be empty

Error messages appear directly below the invalid field. Fix the value and the error clears immediately — no need to re-submit. Server-side errors (like unique constraint violations) still appear as a banner at the bottom of the form.

Click Edit on the detail view. The form is pre-filled with the record’s current values. Change what you need and click Save Changes.

Click Delete on the detail view. A confirmation dialog appears — once confirmed, the record is removed and you’re returned to the list view.

Your permissions depend on your role. Alchemify uses database-level security, so:

  • You only see rows you’re authorized to access
  • The New button only appears if you can insert into that table
  • Edit and Delete only appear if you have update/delete permissions

This is all enforced by PostgreSQL — the app reflects what the database allows.