有人知道一个快速简单的方法来迁移SQLite3数据库到MySQL吗?


当前回答

http://sqlfairy.sourceforge.net/ http://search.cpan.org/dist/SQL-Translator/

aptitude install sqlfairy libdbd-sqlite3-perl

sqlt -f DBI --dsn dbi:SQLite:../.open-tran/ten-sq.db -t MySQL --add-drop-table > mysql-ten-sq.sql
sqlt -f DBI --dsn dbi:SQLite:../.open-tran/ten-sq.db -t Dumper --use-same-auth > sqlite2mysql-dumper.pl
chmod +x sqlite2mysql-dumper.pl
./sqlite2mysql-dumper.pl --help
./sqlite2mysql-dumper.pl --add-truncate --mysql-loadfile > mysql-dump.sql
sed -e 's/LOAD DATA INFILE/LOAD DATA LOCAL INFILE/' -i mysql-dump.sql

echo 'drop database `ten-sq`' | mysql -p -u root
echo 'create database `ten-sq` charset utf8' | mysql -p -u root
mysql -p -u root -D ten-sq < mysql-ten-sq.sql
mysql -p -u root -D ten-sq < mysql-dump.sql

其他回答

最近,为了我们团队正在进行的一个项目,我不得不从MySQL迁移到JavaDB。我发现Apache编写的一个名为DdlUtils的Java库非常容易做到这一点。它提供了一个API,让你做以下事情:

发现数据库的模式并将其导出为XML文件。 根据此模式修改DB。 将记录从一个DB导入到另一个DB,假设它们具有相同的模式。

我们最终使用的工具并不是完全自动化的,但它们工作得很好。即使您的应用程序不是用Java编写的,使用一些小工具进行一次性迁移也不会太难。我认为我只用了不到150行代码就完成了迁移。

最简单的方法可能是使用sqlite .dump命令,在本例中创建示例数据库的转储。

sqlite3 sample.db .dump > dump.sql

然后(理论上)您可以使用root用户将其导入到mysql数据库中,在本例中是数据库服务器127.0.0.1上的测试数据库。

mysql -p -u root -h 127.0.0.1 test < dump.sql

我说在理论上,因为语法之间有一些差异。

在sqlite事务开始

BEGIN TRANSACTION;
...
COMMIT;

MySQL只使用

BEGIN;
...
COMMIT;

还有其他类似的问题(varchars和双引号会回到脑海中),但没有查找和替换不能解决的问题。

也许你应该问问为什么要迁移,如果性能/数据库大小是问题,也许应该考虑重新规划模式,如果系统正在迁移到更强大的产品,这可能是计划数据未来的理想时机。

以下是转换器列表(自2011年以来没有更新):

https://www2.sqlite.org/cvstrac/wiki?p=ConverterTools(或在archive.org上快照)

另一种工作得很好但很少被提及的方法是:使用一个ORM类,为您抽象出特定的数据库差异。例如,你在PHP (RedBean), Python (Django的ORM层,Storm, SqlAlchemy), Ruby on Rails (ActiveRecord), Cocoa (CoreData)中得到这些

例如,你可以这样做:

使用ORM类从源数据库加载数据。 将数据存储在内存中或序列化到磁盘。 使用ORM类将数据存储到目标数据库中。

这个脚本是可以的,除了这种情况,当然,我遇到过:

INSERT INTO "requestcomparison_stopword" VALUES(149,'f');
INSERT INTO "requestcomparison_stopword" VALUES(420,'t');

脚本应该给出这样的输出:

INSERT INTO requestcomparison_stopword VALUES(149,'f');
INSERT INTO requestcomparison_stopword VALUES(420,'t');

而是给出了输出:

INSERT INTO requestcomparison_stopword VALUES(1490;
INSERT INTO requestcomparison_stopword VALUES(4201;

最后0和1周围有一些奇怪的非ascii字符。

当我注释以下代码行(43-46)时,这不再出现,但出现了其他问题:

行= re.sub (r”([^”)“t”(.)”、“this_is_true 1 \ \ 2”、线) Line = Line。替换(' THIS_IS_TRUE ', ' 1 ') 行= re.sub (r”([^])的f '(。)”、“this_is_false 1 \ \ 2”、线) Line = Line。替换(“THIS_IS_FALSE ', ' 0 ')

这只是一个特殊的情况,当我们想要添加一个值是“f”或“t”,但我不太习惯正则表达式,我只是想发现这种情况由某人纠正。

无论如何,非常感谢这个方便的脚本!!

每个人似乎都是从一些grep和perl表达式开始的,你可能会得到一些适用于特定数据集的东西,但你不知道它是否正确地导入了数据。我真的很惊讶没有人建立一个可靠的库,可以在两者之间转换。

这里列出了我所知道的两种文件格式之间SQL语法的所有差异: 以以下几行开头:

开始事务 提交 sqlite_sequence 创建唯一索引

在MySQL中不使用

SQLite uses CREATE TABLE/INSERT INTO "table_name" and MySQL uses CREATE TABLE/INSERT INTO table_name MySQL doesn't use quotes inside the schema definition MySQL uses single quotes for strings inside the INSERT INTO clauses SQLite and MySQL have different ways of escaping strings inside INSERT INTO clauses SQLite uses 't' and 'f' for booleans, MySQL uses 1 and 0 (a simple regex for this can fail when you have a string like: 'I do, you don't' inside your INSERT INTO) SQLLite uses AUTOINCREMENT, MySQL uses AUTO_INCREMENT

这是一个非常基本的perl脚本,它适用于我的数据集,并检查了我在网上找到的其他perl脚本的更多这些条件。Nu保证它将为您的数据工作,但请随意修改和发布回这里。

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){
        
        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/i){
            $name = $1;
            $sub = $2;
            $sub =~ s/\"//g;
            $line = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";
        }
        elsif ($line =~ /INSERT INTO \"([a-z_]*)\"(.*)/i){
            $line = "INSERT INTO $1$2\n";
            $line =~ s/\"/\\\"/g;
            $line =~ s/\"/\'/g;
        }else{
            $line =~ s/\'\'/\\\'/g;
        }
        $line =~ s/([^\\'])\'t\'(.)/$1THIS_IS_TRUE$2/g;
        $line =~ s/THIS_IS_TRUE/1/g;
        $line =~ s/([^\\'])\'f\'(.)/$1THIS_IS_FALSE$2/g;
        $line =~ s/THIS_IS_FALSE/0/g;
        $line =~ s/AUTOINCREMENT/AUTO_INCREMENT/g;
        print $line;
    }
}