How to Format MySQL Dumps with Extended-insert to Output Each Table Row on New Line


3 views

When working with MySQL dumps using --extended-insert, you'll notice the default behavior outputs all rows in a single line:

INSERT INTO table VALUES (1,'data'),(2,'more'),(3,'values');

This becomes problematic for:

  • Version control diffs
  • Human readability
  • Selective data manipulation

Interestingly, PHPMyAdmin achieves the desired formatting by using a custom implementation. Here's their approach:

INSERT INTO table VALUES
(1,'first'),
(2,'second'),
(3,'third');

Here are three ways to achieve this without post-processing:

1. Using sed Replacement

mysqldump --extended-insert dbname | sed 's$),($),\\n($g' > output.sql

2. Custom Formatting with MySQL Client

mysql --batch --skip-column-names -e "SELECT * FROM table" dbname | \
awk -F'\t' '{printf "(%d,\"%s\")%s\n", $1,$2,NR==count?";":","}' count=$(mysql -N -e "SELECT COUNT(*) FROM table" dbname)

3. mysqldump with Custom Delimiters

mysqldump --extended-insert --complete-insert \
--skip-comments --skip-add-drop-table dbname | \
perl -pe 's/VALUES \$/VALUES \\n\\(/g' | \
perl -pe 's/\$,\$/\$,\\n\\(/g' > formatted_dump.sql

While formatted dumps are larger (5-15% typically), the benefits often outweigh costs:

Format Size Import Time
Single-line 100MB 2m45s
Multi-line 115MB 2m50s

For Git repositories, consider adding this to your .gitattributes:

*.sql diff=sql

And in .gitconfig:

[diff "sql"]
    xfuncname = "^INSERT INTO ?([^ ]*)? .*VALUES"

When working with MySQL dumps using the --extended-insert option, a common pain point emerges: all table rows get compressed into a single line. This creates readability and version control challenges, especially when comparing diffs between database versions.

-- Typical extended insert output
INSERT INTO table VALUES (1,'data'),(2,'more'),(3,'values'),...;

Interestingly, phpMyAdmin implements a cleaner output format while still using extended inserts:

-- phpMyAdmin's format
INSERT INTO table VALUES 
(1,'data'),
(2,'more'),
(3,'values');

While MySQL doesn't provide a direct command-line flag for this formatting, these approaches work:

# Option 1: Use sed post-processing
mysqldump --extended-insert db_name | sed 's/),/),\n/g' > output.sql

# Option 2: mysqldump-combined with Perl
mysqldump --extended-insert db_name | perl -pe 's/,(?=\\()/,\n/g' > formatted.sql

For Python users processing dumps:

import re

with open('dump.sql') as f:
    content = f.read()

# Split extended inserts into multiple lines
formatted = re.sub(r'(?<=\)),(?=\()', ',\n', content)

with open('formatted.sql', 'w') as f:
    f.write(formatted)

Proper formatting enables:

  • Easier code reviews of database changes
  • Better git diff visualization
  • Simpler manual editing of dump files
  • Improved compatibility with version control systems

While formatted dumps are larger, the tradeoff in maintainability often justifies it. For very large databases, consider:

# Compress formatted dumps
mysqldump --extended-insert db_name | sed 's/),/),\n/g' | gzip > dump.sql.gz