2013-11-08 7 views
0

Я использую mysql2sqlite.sh из сценария Github, чтобы изменить базу данных mysql на sqlite. Но проблема, которую я получаю, заключается в том, что в моей таблице данные 'E-001' изменен на 'E? 001'.mysql2sqlite.sh скрипт не работает по мере необходимости

Я не знаю, как изменить скрипт, чтобы получить требуемый результат. Пожалуйста, помогите мне.

сценарий

#!/bin/sh 

# Converts a mysqldump file into a Sqlite 3 compatible file. It also extracts the MySQL `KEY xxxxx` from the 
# CREATE block and create them in separate commands _after_ all the INSERTs. 

# Awk is choosen because it's fast and portable. You can use gawk, original awk or even the lightning fast mawk. 
# The mysqldump file is traversed only once. 

# Usage: $ ./mysql2sqlite mysqldump-opts db-name | sqlite3 database.sqlite 
# Example: $ ./mysql2sqlite --no-data -u root -pMySecretPassWord myDbase | sqlite3 database.sqlite 

# Thanks to and @artemyk and @gkuenning for their nice tweaks. 

mysqldump --compatible=ansi --skip-extended-insert --compact "[email protected]" | \ 

awk ' 

BEGIN { 
FS=",$" 
print "PRAGMA synchronous = OFF;" 
print "PRAGMA journal_mode = MEMORY;" 
print "BEGIN TRANSACTION;" 
} 

# CREATE TRIGGER statements have funny commenting. Remember we are in trigger. 
/^\/\*.*CREATE.*TRIGGER/ { 
gsub(/^.*TRIGGER/, "CREATE TRIGGER") 
print 
inTrigger = 1 
next 
} 

# The end of CREATE TRIGGER has a stray comment terminator 
/END \*\/;;/ { gsub(/\*\//, ""); print; inTrigger = 0; next } 

# The rest of triggers just get passed through 
inTrigger != 0 { print; next } 

# Skip other comments 
/^\/\*/ { next } 

# Print all `INSERT` lines. The single quotes are protected by another single quote. 
/INSERT/ { 
gsub(/\\\047/, "\047\047") 
gsub(/\\n/, "\n") 
gsub(/\\r/, "\r") 
gsub(/\\"/, "\"") 
gsub(/\\\\/, "\\") 
gsub(/\\\032/, "\032") 
print 
next 
} 

# Print the `CREATE` line as is and capture the table name. 
/^CREATE/ { 
print 
if (match($0, /\"[^\"]+/)) tableName = substr($0, RSTART+1, RLENGTH-1) 
} 

# Replace `FULLTEXT KEY` or any other `XXXXX KEY` except PRIMARY by `KEY` 
/^ [^"]+KEY/ && !/^ PRIMARY KEY/ { gsub(/.+KEY/, " KEY") } 

# Get rid of field lengths in KEY lines 
/KEY/ { gsub(/\([0-9]+\)/, "") } 

# Print all fields definition lines except the `KEY` lines. 
/^/&& !/^(KEY|\);)/ { 
gsub(/AUTO_INCREMENT|auto_increment/, "") 
gsub(/(CHARACTER SET|character set) [^ ]+ /, "") 
gsub(/DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP|default current_timestamp on update current_timestamp/, "") 
gsub(/(COLLATE|collate) [^ ]+ /, "") 
gsub(/(ENUM|enum)[^)]+\)/, "text ") 
gsub(/(SET|set)\([^)]+\)/, "text ") 
gsub(/UNSIGNED|unsigned/, "") 
if (prev) print prev "," 
prev = $1 
} 

# `KEY` lines are extracted from the `CREATE` block and stored in array for later print 
# in a separate `CREATE KEY` command. The index name is prefixed by the table name to 
# avoid a sqlite error for duplicate index name. 
/^(KEY|\);)/ { 
if (prev) print prev 
prev="" 
if ($0 == ");"){ 
print 
} else { 
if (match($0, /\"[^"]+/)) indexName = substr($0, RSTART+1, RLENGTH-1) 
if (match($0, /\([^()]+/)) indexKey = substr($0, RSTART+1, RLENGTH-1) 
key[tableName]=key[tableName] "CREATE INDEX \"" tableName "_" indexName "\" ON \"" tableName "\" (" indexKey ");\n" 
} 
} 

# Print all `KEY` creation lines. 
END { 
for (table in key) printf key[table] 
print "END TRANSACTION;" 
} 
' 
exit 0 

ответ

1

Я не могу дать гарантированное решение, но вот простой метод я использую, чтобы успешно справиться с подобными проблемами (см «Примечания», ниже). Я боролся с этим сценарием последние несколько дней, и считаю, что это стоит поделиться, если есть другие, которые нуждаются в его настройке, но они заглушены кривой обучения awk.

Основная идея состоит в том, чтобы вывести скрипт в текстовый файл, отредактировать файл, , затем импорт в sqlite (более подробные инструкции ниже).

Возможно, вам придется немного поэкспериментировать, но по крайней мере вам не придется изучать awk (хотя я пытался, и это очень весело ...).

КАК

  • Запустите сценарий, экспорт в файл (вместо прохождения непосредственно в sqlite3):

    ./mysql2sqlite -u root -pMySecretPassWord myDbase > sqliteimport.sql

  • использовать ваши предпочитаемые редактирования текста техника, чтобы очистить все беспорядки , с которыми вы столкнулись. Например, поиск/замена в sublimetext. (См последней ноты, ниже, для чаевых.)

  • Импорта очищенного скрипта в SQLite:

    sqlite3 database.sqlite < sqliteimport.sql

ПРИМЕЧАНИЕ:

  • I подозревайте, что вы имеете дело с проблемой кодирования - что '-' представляет собой символ, который не распознается, или означает что-то другое арендовать, либо вашу оболочку, скрипт (awk), либо вашу базу данных sqlite. В зависимости от вашей ситуации вы не сможете усовершенствовать проблему (см. Следующую заметку).

  • Предупреждает, что это, скорее всего, будет только работать, если персонажи обижая встроены в тексте данных (а не только , как текста, но фактическое содержание текст хранится в текстовом поля). Если они находятся в имени машины (поле внешнего ключа, идентификатор объекта, например), двоичные данные, хранящиеся в виде текста, или текстовые данные, хранящиеся в двоичном поле (например, blob), будьте осторожны. Вы можете попробовать, но не надейтесь, и даже если это кажется, чтобы работать, не забудьте проверить его.

  • Если на самом деле символ '-' представляет собой необычный символ, вы, вероятно, не сможете просто ввести дефис в поле поиска вашего инструмента поиска/замены. Скопируйте его из исходных данных (например, откройте файл, выделите и скопируйте в буфер обмена), затем вставьте его в инструмент.

Надеюсь, это поможет!

-1

Для преобразования mysql в sqlite3 вы можете использовать Navicom Premium.

Смежные вопросы