Three situations keep coming up:
- Stand up a schema for staging or CI — you want the empty table structure so tests can run against real columns, indexes and constraints, but you absolutely do not want to ship gigabytes of production rows into a throwaway environment.
- Seed data only — the schema already exists in the target database, and you just need the INSERT rows to populate it, without CREATE statements that would collide with what's there.
- Get rid of noise — the dump is bloated by
logs,sessions,audit_trailorcachetables with tens of millions of rows you never want to import.
Why mysqldump --no-data isn't enough
The classic advice is mysqldump --no-data (structure only) or mysqldump --no-create-info (data only). Both are export flags: they change what a fresh dump from a running database contains. They do nothing for a dump you already have sitting on disk as a .sql file.
In practice the file often arrives from someone else, or from a backup job, or from a server you no longer have live access to. You can't re-run mysqldump against a database that isn't reachable — the credentials are gone, the server is decommissioned, or the file is simply all you were handed. At that point the flags are useless, and you're left editing the file itself.
The manual way
The obvious move is to strip lines with grep or sed. To keep structure and drop the data:
# keep everything except INSERT rows grep -v '^INSERT INTO' dump.sql > schema.sql # or keep only the INSERT rows for a data-only file grep '^INSERT INTO' dump.sql > data.sql
This looks fine on a small, tidy dump — and then breaks on a real one:
- Multi-line INSERTs. A single
INSERT INTO … VALUEScan span thousands of lines.grepmatches the first line and leaves the rest of the values orphaned, producing a broken file. - Extended inserts. mysqldump batches many rows into one giant statement. Line-based filters can't tell where such a statement ends.
- Comments and blocks. Conditional
/*! … */blocks,LOCK TABLES, and--comments interleave with the data, so a naive filter either keeps junk or cuts something the import needs. - Data-only is worse. A pure
grep '^INSERT'throws away theSETandLOCKstatements the rows depend on, and any INSERT that doesn't start exactly at column zero silently disappears.
You end up debugging your own filter instead of getting your schema.
Structure-only or data-only with DumpCleaner
DumpCleaner understands SQL statements instead of matching lines, so it splits structure from data reliably — on files of any size:
- Drag your
.sqldump into DumpCleaner (MySQL, MariaDB or PostgreSQL). It parses the file by streaming, so a multi-gigabyte dump loads with constant memory. - Toggle the statement types you want: CREATE TABLE, CREATE INDEX, INSERT INTO, ALTER, DROP, LOCK, SET. Uncheck INSERT INTO and you get structure only; uncheck CREATE TABLE / CREATE INDEX and you get data only.
- Or pick a preset — Structure only or Data only — to set every toggle in one step, then refine per table if you like.
- Export. You get a lean schema file for staging or CI, or a clean data-only dump for seeding.
Because the filter is statement-aware, a multi-line extended INSERT is kept or dropped as a whole — never cut in the middle.
The real power is that filtering works per statement type and per table, and the two combine. You can keep the structure of every table but include INSERT data only for the three tables you actually need — leaving the 89-million-row logs table as an empty shell. That's something no --no-data flag can express.
Split structure from data in seconds
DumpCleaner filters an existing dump by statement type and by table — structure only, data only, or any mix — streaming, with constant memory. Native macOS & iPadOS app, one-time purchase.
Download on the App StoreFrequently asked questions
Can I export the data without the schema?
Yes. Disable CREATE TABLE and CREATE INDEX (or pick the Data only preset) and keep INSERT INTO. DumpCleaner exports just the rows, ready to load into a schema that already exists.
Does a structure-only export keep indexes and foreign keys?
Yes. Structure only keeps CREATE TABLE, CREATE INDEX, ALTER TABLE and the foreign key definitions — everything that defines the database. Only the INSERT data rows are removed.
Can I mix — structure for all tables, data for some?
Yes. Filtering is per statement type and per table, and both combine. Keep the structure of every table but include INSERT data only for the few tables you actually need.
Does this work with PostgreSQL?
Yes. DumpCleaner reads MySQL, MariaDB and PostgreSQL dumps and detects the format automatically, so structure-only and data-only exports work the same way for pg_dump files.
Schema without the data — or data without the schema
Drag, toggle the statement types, export. DumpCleaner splits any dump into exactly the part you need.
Download on the App Store