MySQL nach SQLite exportieren

Zum Exportieren von MySQL-Datenbanken nach SQLite gibt es bei http://www.sqlite.org/ ein kleines Shellscript, das aber bei mir leider nicht so ganz zufriedenstellend funktionieren wollte. Vor allem nicht mit diesem Beitrag hier ;) Darum habe ich mir erlaubt, das Script ein wenig zu modifizieren:

#!/bin/sh
if [ "x$1" == "x" ]; then
    echo "Usage: $0 <dbname>"
    exit
fi

if [ -e "$1.db" ]; then     echo "$1.db already exists. I will overwrite it in 15 seconds if you do not press CTRL-C."     COUNT=15     while [ $COUNT -gt 0 ]; do         echo "$COUNT"         sleep 1         COUNT=$((COUNT — 1))     done     rm $1.db fi

mysqldump -u root -p --compact --compatible=ansi --default-character-set=binary $1 | grep -v '^\( KEY "\)' | grep -v '^\( UNIQUE KEY "\)' | grep -v '^\( PRIMARY KEY \)' | grep -v '^\(SET \)' | sed 's/ / /g' | sed 's/ primary key autoincrement/ primary key autoincrement/gi' | sed 's/ smallint([0-9]*) / integer /gi' | sed 's/ tinyint([0-9]*) / integer /gi' | sed 's/ int([0-9]*) / integer /gi' | sed 's/ ]* / /gi' | sed 's/ enum([^)]*) / varchar(255) /gi' | sed 's/,]*//gi' | sed 's/\\//g' | sed 's/\\"/"/g' | perl -e 'local $/;$_=<>;s/,\n\)/\n\)/gs;print "begin;\n";print;print "commit;\n"' | perl -pe ' if (/^(INSERT.+?)\(/) {     $a=$1;     s/\\'\''/'\'\''/g;     s/\\n/\n/g;     s/\),\(/\);\n$a\(/g; } ' > $1.sql

cat $1.sql | sqlite3 $1.db > $1.err ERRORS=`cat $1.err | wc -l` if [ "$ERRORS" == "0" ]; then     echo "Conversion completed without error. Output file: $1.db"     rm $1.sql     rm $1.err else     echo "There were errors during conversion. Please review $1.err and $1.sql for details." fi

Leider werden mit dieser Version alle Zeilenumbrüche, die innerhalb eines INSERT INTO <table> in der Form \n erscheinen, durch tatsächliche Zeilenumbrüche ersetzt. In Codebeispielen innerhalb von Artikeln können aber auch \n vorkommen, siehe oben. Solche Codebeispiele werden dann zu wirrem Wirrwarr. Also muß noch eine weitere Verbessserung eingebaut werden.

Allerdings ist es etwas kniffelig, mit Regexen die zu ersetzenden \n von denen, die in Codebeispielen drinbleiben sollen, zu unterscheiden. Ich habe zwar ein paar Sachen mit Backreferences ausprobiert, aber aus Zeitmangel gab ich mich vorerst damit zufrieden, in obigem Script die Zeile

s/\\n/\n/g;

durch

s/(?<!(\s<code>))(\\n)(?!(\\\)|(\"))|(\/)|(\$)|(\)))/\n/g;

zu ersetzen. Das ist vielleicht nicht besonders elegant und deckt natürlich lange nicht alle denkbaren Fälle ab, in denen \n in Codebeispiel-Zeilen erscheinen kann. Wenn meine Muße es zuläßt, werde ich demnächst eine bessere Lösung suchen, hoffentlich finden und hier veröffentlichen.

Add post to: Delicious Reddit Slashdot Digg Technorati Google
(already: 1) Comment post

Comments

No comments for this post

Required. 30 chars of fewer.

Required.

captcha image Please, enter symbols, which you see on the image