0

我正在使用脚本Github 中的 mysql2sqlite.sh 将我的 mysql 数据库更改为 sqlite。但我遇到的问题是,在我的表中,数据'E-001'更改为'E?001'

我不知道如何修改脚本以获得所需的结果。请帮我。

脚本是

#!/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 "$@" | \

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
4

2 回答 2

1

我不能给出一个有保证的解决方案,但这是我成功使用来处理类似问题的一种简单技术(参见下面的“注释”)。过去几天我一直在与这个脚本搏斗,并且认为这是值得分享的,以防其他人需要调整它但被 awk 学习曲线所阻碍。

基本思想是将脚本输出到文本文件,编辑文件,然后导入 sqlite(下面有更详细的说明)。

您可能需要进行一些实验,但至少您不必学习 awk(尽管我一直在尝试并且它很有趣......)。

如何

  • 运行脚本,导出到文件(而不是直接传递给 sqlite3):

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

  • 使用您喜欢的文本编辑技术来清理您遇到的任何混乱。例如,在 sublimetext 中搜索/替换。(有关提示,请参阅下面的最后一个注释。)

  • 将清理后的脚本导入 sqlite:

    sqlite3 database.sqlite < sqliteimport.sql

笔记:

  • 我怀疑你正在处理的是一个编码问题——'-' 代表一个字符,它不能被你的 shell、脚本(awk)或你的 sqlite 数据库识别或意味着不同的东西。根据您的情况,您可能无法解决问题(请参阅下一个注释)。

  • 请注意,这很可能仅在违规字符嵌入文本数据(不仅仅是文本,而是存储在文本字段中的实际文本内容)时才会起作用。如果它们位于机器名称(外键字段、实体 ID,例如)、存储为文本的二进制数据或存储在二进制字段(例如 blob)中的文本数据中,请小心。你可以试一试,但不要抱太大希望,即使它看起来有效,也一定要试一试。

  • 如果事实上“-”代表一些不寻常的字符,您可能无法在搜索/替换工具的“搜索”字段中输入连字符。从源数据中复制它(例如,打开文件,突出显示并复制到剪贴板),然后粘贴到工具中。

希望这可以帮助!

于 2013-12-12T18:19:44.780 回答
-1

要将 mysql 转换为 sqlite3,您可以使用 Navicom Premium。

于 2017-05-27T15:50:53.143 回答