# Export your schema Once a schema is on the canvas, you can take it out in five different shapes depending on where it is going. ## The formats | Format | File | For | |---|---|---| | **Bubble JSON** | `.json` | Re-importing into LumiDevKit, or archiving | | **Postgres SQL** | `.sql` | Pasting into the Supabase SQL editor | | **Markdown** | `.md` | A human-readable data dictionary | | **Prisma** | `.prisma` | A `schema.prisma` for Prisma ORM | | **Drizzle** | `.ts` | A Drizzle `pg-core` schema | The last four are behind the **Export as…** button. Bubble JSON is the separate **Download JSON** action, and it is the round-trip format: what comes out can be uploaded straight back in. [[img:export-your-schema/01-export-modal.png|The Export as… dialog. Pick a format, decide whether simple option sets become native ENUM types, then download the file or take it straight to the clipboard.]] Two actions produce no file at all. **Copy for Bubble** puts the schema on the clipboard for the LumiDevKit extension — see [push a schema into Bubble](/docs/copy-for-bubble). **Copy SQL for Supabase** puts the Postgres SQL on the clipboard for the Supabase SQL editor, always with option sets as lookup tables, so use **Export as…** if you want the ENUM choice. ## How relationships translate to SQL - A single reference becomes a `_id uuid` column with a deferred `ALTER TABLE … ADD CONSTRAINT … FOREIGN KEY`. Deferring the constraints means a schema with reference cycles still runs top to bottom. - A list of references becomes a junction table named `_`, with a `position` column so ordering survives, marked `COMMENT ON TABLE … IS 'lumidevkit:join'`. - A list of plain values becomes a Postgres array column. - Bubble's built-in User becomes a `public.profiles` table keyed to `auth.users(id)`, the Supabase convention. It is only emitted if something actually references the User. - Tables are emitted in dependency order. Every data-type table gets `id uuid PRIMARY KEY DEFAULT gen_random_uuid()`, `created_at` and `updated_at`. None of the tables LumiDevKit generates for you carries that full set: a junction table carries its two foreign keys and `position` under a composite primary key, an option set lookup table carries `id`, `value`, `label` and `sort_order`, and `profiles` carries `id` (the foreign key to `auth.users`) and `created_at`. ## Option sets: lookup tables or native enums By default an option set becomes a `_options` lookup table with `value`, `label` and `sort_order` columns, plus an `INSERT` block seeding its values. The **"Emit simple option sets as native ENUM types"** checkbox switches to `CREATE TYPE … AS ENUM` — but only for option sets that qualify: they must have no custom attributes and must not be used by any list-of-options field. Anything that does not qualify stays a lookup table even with the box ticked, because an enum cannot carry attributes or be used as a list. ## Round-trip fidelity SQL export and import are designed to round-trip, which is why the export writes `lumidevkit:` comment markers. Display names that differ from what would be derived from the column name are preserved as `COMMENT ON COLUMN` markers. What does not survive a round trip: privacy rules, deleted items (they are skipped on export), and Bubble types the diagram does not model such as `date_range`. ## Deleted items The four **Export as…** formats exclude deleted data types, deleted option sets and deleted fields. If you want them in SQL, Markdown, Prisma or Drizzle, undelete them in Bubble first. The Bubble JSON download is the exception. Its dialog has an **Include Deleted** checkbox under Data Types and another under Option Sets, both off by default, so deleted items only ship when you ask for them. ## Related - [Import a Postgres schema](/docs/import-a-postgres-schema) - [Push a schema into Bubble](/docs/copy-for-bubble)