metabase-export
A command-line tool that reads Metabase’s native (SQL) questions from its application database and writes them to disk as a tree of .sql files that mirrors the collections. Your report SQL lives in git instead of only inside Metabase.
Usage
uvx metabase-export --output reports
Every run rewrites the output directory. It is a mirror, not a merge: a card deleted or archived in Metabase disappears from disk. Directories whose name starts with _ are never touched.
It needs read access to the Metabase application database (metabaseappdb), not to the databases Metabase reports against. The password comes from METABASE_PG_PASSWORD or a prompt — never from a flag.
uvx metabase-export --output reports --root-collection 4 # one collection
uvx metabase-export --output reports --dry-run # change nothing
uvx metabase-export --output reports --port 15433 --ssh-host prod-box
The collection id comes from its URL: /collection/4-my-reports → 4.
| Option | Default | |
|---|---|---|
--output DIR | reports | where to write the tree |
--dry-run | off | list changes, write nothing |
--root-collection ID | all | export only this collection and its children |
--host --port --user --dbname | 127.0.0.1 5432 postgres metabaseappdb | connection |
--ssh-host HOST | — | tunnel --port through this host if it is closed |
--remote-port PORT | 5432 | Postgres port on the far side |
Each option has an env var (METABASE_EXPORT_DIR, METABASE_PG_HOST, …; see --help), so a project can pin its settings and run with no arguments.
Notes
- Only native (SQL) questions. Query-builder questions have no SQL and are skipped.
- Reads MBQL5 (Metabase 50+) and the older
native.queryformat. - Output is deterministic: two runs in a row leave the tree untouched.
- Files keep
{{parameter}}placeholders, so they are not runnable outside Metabase.
Motivation
I had many questions saved in Metabase and backing them up or versioning them was hard: they lived only inside the tool, with no history and no way to get them into git without copying them by hand. metabase-export was born to fix that.