SQLite3をMySQLに移行する簡単な方法は?[閉まっている]


224

SQLite3データベースをMySQLに移行する簡単な方法を知っている人はいますか?

回答:


62

以下はコンバーターのリストです(2011年以降更新されていません)。


うまく機能するがめったに言及されない代替方法は、特定のデータベースの違いを抽象化するORMクラスを使用することです。たとえば、これらはPHP(RedBean)、Python(DjangoのORMレイヤー、StormSqlAlchemy)、Ruby on Rails(ActiveRecord)、Cocoa(CoreData)で取得します。

つまり、これを行うことができます:

  1. ORMクラスを使用して、ソースデータベースからデータをロードします。
  2. データをメモリに保存するか、ディスクにシリアル化します。
  3. ORMクラスを使用してデータを宛先データベースに格納します。

107

誰もがいくつかのgrepsとperlの式で開始するようで、特定のデータセットで機能するものを取得できますが、データが正しくインポートされたかどうかはわかりません。この2つを変換できる堅固なライブラリーを誰も作成していないことに、私は真剣に驚いています。

ここに、2つのファイル形式の間で私が知っているSQL構文のすべての違いのリストがあります。

  • トランザクションを開始
  • コミット
  • sqlite_sequence
  • 一意のインデックスを作成

MySQLでは使用されません

  • SQLliteの使用CREATE TABLE/INSERT INTO "table_name"とMySQLの使用CREATE TABLE/INSERT INTO table_name
  • MySQLはスキーマ定義内で引用符を使用しません
  • MySQLはINSERT INTO句内の文字列に一重引用符を使用します
  • SQLliteとMySQLでは、INSERT INTO句内の文字列をエスケープする方法が異なります
  • SQLliteが使用't''f'、ブール値の場合、MySQLは1andを使用します0(このための単純な正規表現は、「I do、you don \ 't」のような文字列があると失敗する可能性がありますINSERT INTO
  • SQLLiteはAUTOINCREMENT、MySQLはAUTO_INCREMENT

これは、私のデータセットで機能する非常に基本的なハッキングされたperlスクリプトで、他のperlスクリプトがWebで見つけたこれらの条件の多くをチェックします。それはあなたのデータのために働くことを保証しますが、ここで自由に修正して投稿してください。

#! /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;
    }
}

8
アレックスマルテッリは、stackoverflow.com
questions / 1067060 / perl

私は完全なpythonスクリプトを追加しました(perlスクリプトだけでは十分に機能しませんでした...外部キーとインデックスを処理するために追加の処理が必要でした)
Jiaaro

私は他の質問でこの回答を書き直しましたstackoverflow.com/questions/1067060/_/1070463#1070463
Brad Gilbert

2
COMMITCREATE UNIQUE INDEXは有効なMySQLコマンドです。修正してください。
niutech 2013

5
*後:私はここにいくつかの追加/バグ修正だ、あなたのスクリプトは、「迅速かつ汚い」だけでなく、非常に有用であることを理解&& ($line !~ /CREATE UNIQUE INDEX/)アドオン&& ($line !~ /PRAGMA foreign_keys=OFF/) テーブル名マッチング正規表現ミス桁*、代わりにあるもの$line =~ /INSERT INTO \"([a-z_]*)\"(.*)/がなければならない$line =~ /INSERT INTO \"([a-z_1-9]*)\"(.*)/ 、これは将来の役に立てば幸い読者
のMichałレオン

50

これは、Shalmaneseの回答と、PerlからPythonへの変換での Alex martelliからの助けを基に構築されたpythonスクリプトです。

私はコミュニティwikiを作っているので、機能を壊さない限り、自由に編集してリファクタリングしてください(ありがたいことに、ロールバックできるだけです)-かなり見苦しいですが、機能します

そのように使用します(スクリプトが次のように呼び出されると仮定しますdump_for_mysql.py

sqlite3 sample.db .dump | python dump_for_mysql.py > dump.sql

mysqlにインポートできるもの

注-sqliteは実際には外部キー制約をサポートしていないため、手動で外部キー制約を追加する必要があります

ここにスクリプトがあります:

#!/usr/bin/env python

import re
import fileinput

def this_line_is_useless(line):
    useless_es = [
        'BEGIN TRANSACTION',
        'COMMIT',
        'sqlite_sequence',
        'CREATE UNIQUE INDEX',
        'PRAGMA foreign_keys=OFF',
    ]
    for useless in useless_es:
        if re.search(useless, line):
            return True

def has_primary_key(line):
    return bool(re.search(r'PRIMARY KEY', line))

searching_for_end = False
for line in fileinput.input():
    if this_line_is_useless(line):
        continue

    # this line was necessary because '');
    # would be converted to \'); which isn't appropriate
    if re.match(r".*, ''\);", line):
        line = re.sub(r"''\);", r'``);', line)

    if re.match(r'^CREATE TABLE.*', line):
        searching_for_end = True

    m = re.search('CREATE TABLE "?(\w*)"?(.*)', line)
    if m:
        name, sub = m.groups()
        line = "DROP TABLE IF EXISTS %(name)s;\nCREATE TABLE IF NOT EXISTS `%(name)s`%(sub)s\n"
        line = line % dict(name=name, sub=sub)
    else:
        m = re.search('INSERT INTO "(\w*)"(.*)', line)
        if m:
            line = 'INSERT INTO %s%s\n' % m.groups()
            line = line.replace('"', r'\"')
            line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", "\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')

    # Add auto_increment if it is not there since sqlite auto_increments ALL
    # primary keys
    if searching_for_end:
        if re.search(r"integer(?:\s+\w+)*\s*PRIMARY KEY(?:\s+\w+)*\s*,", line):
            line = line.replace("PRIMARY KEY", "PRIMARY KEY AUTO_INCREMENT")
        # replace " and ' with ` because mysql doesn't like quotes in CREATE commands 
        if line.find('DEFAULT') == -1:
            line = line.replace(r'"', r'`').replace(r"'", r'`')
        else:
            parts = line.split('DEFAULT')
            parts[0] = parts[0].replace(r'"', r'`').replace(r"'", r'`')
            line = 'DEFAULT'.join(parts)

    # And now we convert it back (see above)
    if re.match(r".*, ``\);", line):
        line = re.sub(r'``\);', r"'');", line)

    if searching_for_end and re.match(r'.*\);', line):
        searching_for_end = False

    if re.match(r"CREATE INDEX", line):
        line = re.sub('"', '`', line)

    if re.match(r"AUTOINCREMENT", line):
        line = re.sub("AUTOINCREMENT", "AUTO_INCREMENT", line)

    print line,

2
こんにちはジム、私のデータセットでは、最初のすべてのINSERTステートメントは単一引用符ではなくバッククォートでラップされています。__ DROP TABLE IF EXISTS schema_migrations; CREATE TABLE IF NOT EXISTS schema_migrationsversionvarchar(255)NOT NULL); INSERT INTO schema_migrations VALUES(20100714032840); INSERT INTO schema_migrations VALUES( '20100714033251'); __
David

まあ...それは上には表示されませんが、バッククォートはVALUES内に表示されます([HERE] 20100714032840 [/ HERE])
David

1
MysqlのAUTOINCREMENTはAUTO_INCREMENTです。スクリプトはそれを考慮していません。
ジュゼッペ2013

これはメディアWikiデータベースでは機能しません。多くのエラー:Blobvarデータタイプ、CREATEステートメントのバックティック...
Frank Hintsch

1
動作しません。すべての条件が考慮されるわけではないかもしれません...
Himanshu Bansal

10

おそらく最も簡単な方法は、sqlite .dumpコマンドを使用することです。この場合は、サンプルデータベースのダンプを作成します。

sqlite3 sample.db .dump > dump.sql

次に、(理論的には)これをmysqlデータベースにインポートできます。この場合、ユーザーrootを使用して、データベースサーバー127.0.0.1のテストデータベースにインポートします。

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

文法の間にはいくつかの違いがあるので、私は理論的に言っています。

sqliteトランザクションで開始

BEGIN TRANSACTION;
...
COMMIT;

MySQLは

BEGIN;
...
COMMIT;

他にも同様の問題があります(varcharと二重引用符が思い浮かびます)が、検索と置換で修正できませんでした。

おそらく、移行する理由を尋ねる必要があります。パフォーマンス/データベースサイズが問題である場合は、スキーマの再認識を検討する必要があります。システムがより強力な製品に移行している場合、これはデータの将来を計画するのに理想的な時期かもしれません。


2
しかし、最も困難な作業は、異なる週の文法です
フランソワ


8
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


7

私はこのプロセスを経験したばかりで、このQ / Aには非常に優れたヘルプと情報がたくさんありますが、実用的なソリューションを得るには、さまざまな要素(および他のQ / Aからの要素)をまとめる必要があることがわかりました正常に移行するための注文。

ただし、既存の回答を組み合わせた後でも、INSERTに複数のブールオカレンスが存在する場所ではPythonスクリプトが機能しないため、Pythonスクリプトが完全には機能しないことがわかりました。参照してくださいここでそれがそうだった理由。

だから、私はここに私の答えを投稿したいと思った。もちろん、クレジットは他の場所で貢献してくれた人々に送られます。しかし、私は何かを返して、他の人の時間を節約したかったのです。

以下のスクリプトを投稿します。しかし、最初に、変換の手順は次のとおりです...

OS X 10.7.5 Lionでスクリプトを実行しました。Pythonはそのまま動作しました。

既存のSQLite3データベースからMySQL入力ファイルを生成するには、次のように独自のファイルでスクリプトを実行します。

Snips$ sqlite3 original_database.sqlite3 .dump | python ~/scripts/dump_for_mysql.py > dumped_data.sql

次に、結果のdumped_sql.sqlファイルを、MySQLデータベースが常駐するUbuntu 10.04.4 LTSを実行しているLinuxボックスにコピーしました。

MySQLファイルをインポートするときに発生した別の問題は、一部のUnicode UTF-8文字(特に単一引用符)が正しくインポートされなかったため、コマンドにスイッチを追加してUTF-8を指定する必要がありました。

空の新しいMySQLデータベースにデータを入力する結果のコマンドは次のとおりです。

Snips$ mysql -p -u root -h 127.0.0.1 test_import --default-character-set=utf8 < dumped_data.sql

それを調理させてください、そしてそれはそれであるはずです!前後にデータを精査することを忘れないでください。

したがって、OPが要求したように、方法を知っていれば、それは迅速かつ簡単です!:-)

余談ですが、この移行を検討する前に確信が持てなかったことの1つは、created_atとupdated_atのフィールド値が保持されるかどうかでした。これは、既存の本番データを移行できるためです。

幸運を!

更新

この切り替えを行って以来、今まで気づかなかった問題に気づきました。私のRailsアプリケーションでは、テキストフィールドは「文字列」として定義されており、これがデータベーススキーマに引き継がれます。ここで説明するプロセスの結果、これらはMySQLデータベースでVARCHAR(255)として定義されます。これにより、これらのフィールドサイズに255文字の制限が設定されます。これを超えると、インポート中に暗黙的に切り捨てられます。255より大きいテキスト長をサポートするには、MySQLスキーマでVARCHAR(255)ではなく 'TEXT'を使用する必要があると思います。ここで定義されているプロセスには、この変換は含まれていません。


これが、私のデータで機能するマージおよび修正されたPythonスクリプトです。

#!/usr/bin/env python

import re
import fileinput

def this_line_is_useless(line):
    useless_es = [
        'BEGIN TRANSACTION',
        'COMMIT',
        'sqlite_sequence',
        'CREATE UNIQUE INDEX',        
        'PRAGMA foreign_keys=OFF'
        ]
    for useless in useless_es:
        if re.search(useless, line):
            return True

def has_primary_key(line):
    return bool(re.search(r'PRIMARY KEY', line))

searching_for_end = False
for line in fileinput.input():
    if this_line_is_useless(line): continue

    # this line was necessary because ''); was getting
    # converted (inappropriately) to \');
    if re.match(r".*, ''\);", line):
        line = re.sub(r"''\);", r'``);', line)

    if re.match(r'^CREATE TABLE.*', line):
        searching_for_end = True

    m = re.search('CREATE TABLE "?([A-Za-z_]*)"?(.*)', line)
    if m:
        name, sub = m.groups()
        line = "DROP TABLE IF EXISTS %(name)s;\nCREATE TABLE IF NOT EXISTS `%(name)s`%(sub)s\n"
        line = line % dict(name=name, sub=sub)
        line = line.replace('AUTOINCREMENT','AUTO_INCREMENT')
        line = line.replace('UNIQUE','')
        line = line.replace('"','')
    else:
        m = re.search('INSERT INTO "([A-Za-z_]*)"(.*)', line)
        if m:
            line = 'INSERT INTO %s%s\n' % m.groups()
            line = line.replace('"', r'\"')
            line = line.replace('"', "'")
            line = re.sub(r"(?<!')'t'(?=.)", r"1", line)
            line = re.sub(r"(?<!')'f'(?=.)", r"0", line)

    # Add auto_increment if it's not there since sqlite auto_increments ALL
    # primary keys
    if searching_for_end:
        if re.search(r"integer(?:\s+\w+)*\s*PRIMARY KEY(?:\s+\w+)*\s*,", line):
            line = line.replace("PRIMARY KEY", "PRIMARY KEY AUTO_INCREMENT")
        # replace " and ' with ` because mysql doesn't like quotes in CREATE commands

    # And now we convert it back (see above)
    if re.match(r".*, ``\);", line):
        line = re.sub(r'``\);', r"'');", line)

    if searching_for_end and re.match(r'.*\);', line):
        searching_for_end = False

    if re.match(r"CREATE INDEX", line):
        line = re.sub('"', '`', line)

    print line,

1
ありがとう。上記で現在記述されているスクリプトには、構文エラーがあります。41行目の「else:」が適切なインデントレベルではありません。その上の行をインデントする必要があるのか​​、それとも他に何か起こっているのかは、私にはわかりません。更新しますか?
Dan Tenenbaum 2015

5

私のチームが取り組んでいるプロジェクトでは、最近MySQLからJavaDBに移行する必要がありました。私はこれをかなり簡単にするDdlUtils呼ばれるApacheによって書かれJavaライブラリを見つけました。次のことを可能にするAPIを提供します。

  1. データベースのスキーマを検出し、XMLファイルとしてエクスポートします。
  2. このスキーマに基づいてDBを変更します。
  3. レコードが同じスキーマであると仮定して、あるDBから別のDBにレコードをインポートします。

私たちが最終的に使用したツールは完全に自動化されていませんでしたが、かなりうまく機能しました。アプリケーションがJavaでなくても、いくつかの小さなツールを作成して1回限りの移行を行うことはそれほど難しくありません。150行未満のコードで移行を成功させることができたと思います。


4

スクリプト、コマンドなどは必要ありません...

sqliteデータベースを.csvファイルとしてエクスポートし、phpmyadminを使用してMysqlにインポートするだけです。

私はそれを使用し、それは素晴らしい働きをしました...


組み合わせでは、この、これは私のために働いた唯一の答えです。
cdauth

3

Jimsのソリューションに基づく: SQLite3をMySQLに移行する迅速で簡単な方法?

sqlite3 your_sql3_database.db .dump | python ./dump.py > your_dump_name.sql
cat your_dump_name.sql | sed '1d' | mysql --user=your_mysql_user --default-character-set=utf8 your_mysql_db -p  

これは私にとってはうまくいきます。最初の行をスローするためだけにsedを使用しますが、これはmysqlのようなものではありませんが、dump.pyスクリプトを変更してこの行を破棄することもできます。


1
インポートしたデータにUTF-8エンコードの問題がいくつかありましたが、インポートコマンドに--default-character-set = utf8を追加すると問題が解決したようです。このQ / Aから撮影:stackoverflow.com/questions/346092/...
切れ端

わかりました、これを追加しました-大丈夫ですか?
alekwisnia

はい、追加のスイッチを使用しています。
12

3

SQLダンプを取得する

moose@pc08$ sqlite3 mySqliteDatabase.db .dump > myTemporarySQLFile.sql

MySQLにダンプをインポートする

小さな輸入品の場合:

moose@pc08$ mysql -u <username> -p
Enter password:
....
mysql> use somedb;
Database changed
mysql> source myTemporarySQLFile.sql;

または

mysql -u root -p somedb < myTemporarySQLFile.sql

これにより、パスワードの入力を求められます。注:パスワードを直接入力する場合は、スペースを入れずに、直後に入力する必要があります-p

mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql

より大きなダンプの場合:

mysqlimportまたはBigDumpなどの他のインポートツール

BigDumpは、進行状況バーを提供します。

ここに画像の説明を入力してください


12
これは、sqliteとmysqlのわずかな構文の違いとフラグのために機能しません。それでも手動で変換する必要があります。
dlite922

1

はぁ…これを最初に見つけたらよかった!私の応答はこの投稿でした... mysql dump sqlファイルをsqlite3 dbにインポートできる形式に変換するスクリプト

この2つを組み合わせることが、まさに私が必要とするものです。


sqlite3データベースをrubyで使用する場合は、次のように変更できます。

tinyint([0-9]*) 

に:

sed 's/ tinyint(1*) / boolean/g ' |
sed 's/ tinyint([0|2-9]*) / integer /g' |

悲しいかな、これだけが機能するのは、ブール値のマークが付けられたフィールドに1と0を挿入しても、sqlite3はそれらを1と0として格納するため、次のような処理を行う必要があるためです。

Table.find(:all, :conditions => {:column => 1 }).each { |t| t.column = true }.each(&:save)
Table.find(:all, :conditions => {:column => 0 }).each { |t| t.column = false}.each(&:save)

しかし、すべてのブール値を見つけるためにsqlファイルを調べることは役に立ちました。


1

この簡単なスクリプトはPython3で作成しました。ターミナルシェルを介して呼び出されるインクルードクラスまたはスタンドアロンスクリプトとして使用できます。デフォルトでは、すべての整数をとしてint(11)、文字列をとしてインポートしますvarchar(300)が、それらはすべてコンストラクタまたはスクリプト引数でそれぞれ調整できます。

注: MySQL Connector / Python 2.0.4以降が必要です

以下のコードが読みにくい場合は、GitHub上のソースへのリンクです。https//github.com/techouse/sqlite3-to-mysql

#!/usr/bin/env python3

__author__ = "Klemen Tušar"
__email__ = "techouse@gmail.com"
__copyright__ = "GPL"
__version__ = "1.0.1"
__date__ = "2015-09-12"
__status__ = "Production"

import os.path, sqlite3, mysql.connector
from mysql.connector import errorcode


class SQLite3toMySQL:
    """
    Use this class to transfer an SQLite 3 database to MySQL.

    NOTE: Requires MySQL Connector/Python 2.0.4 or higher (https://dev.mysql.com/downloads/connector/python/)
    """
    def __init__(self, **kwargs):
        self._properties = kwargs
        self._sqlite_file = self._properties.get('sqlite_file', None)
        if not os.path.isfile(self._sqlite_file):
            print('SQLite file does not exist!')
            exit(1)
        self._mysql_user = self._properties.get('mysql_user', None)
        if self._mysql_user is None:
            print('Please provide a MySQL user!')
            exit(1)
        self._mysql_password = self._properties.get('mysql_password', None)
        if self._mysql_password is None:
            print('Please provide a MySQL password')
            exit(1)
        self._mysql_database = self._properties.get('mysql_database', 'transfer')
        self._mysql_host = self._properties.get('mysql_host', 'localhost')

        self._mysql_integer_type = self._properties.get('mysql_integer_type', 'int(11)')
        self._mysql_string_type = self._properties.get('mysql_string_type', 'varchar(300)')

        self._sqlite = sqlite3.connect(self._sqlite_file)
        self._sqlite.row_factory = sqlite3.Row
        self._sqlite_cur = self._sqlite.cursor()

        self._mysql = mysql.connector.connect(
            user=self._mysql_user,
            password=self._mysql_password,
            host=self._mysql_host
        )
        self._mysql_cur = self._mysql.cursor(prepared=True)
        try:
            self._mysql.database = self._mysql_database
        except mysql.connector.Error as err:
            if err.errno == errorcode.ER_BAD_DB_ERROR:
                self._create_database()
            else:
                print(err)
                exit(1)

    def _create_database(self):
        try:
            self._mysql_cur.execute("CREATE DATABASE IF NOT EXISTS `{}` DEFAULT CHARACTER SET 'utf8'".format(self._mysql_database))
            self._mysql_cur.close()
            self._mysql.commit()
            self._mysql.database = self._mysql_database
            self._mysql_cur = self._mysql.cursor(prepared=True)
        except mysql.connector.Error as err:
            print('_create_database failed creating databse {}: {}'.format(self._mysql_database, err))
            exit(1)

    def _create_table(self, table_name):
        primary_key = ''
        sql = 'CREATE TABLE IF NOT EXISTS `{}` ( '.format(table_name)
        self._sqlite_cur.execute('PRAGMA table_info("{}")'.format(table_name))
        for row in self._sqlite_cur.fetchall():
            column = dict(row)
            sql += ' `{name}` {type} {notnull} {auto_increment}, '.format(
                name=column['name'],
                type=self._mysql_string_type if column['type'].upper() == 'TEXT' else self._mysql_integer_type,
                notnull='NOT NULL' if column['notnull'] else 'NULL',
                auto_increment='AUTO_INCREMENT' if column['pk'] else ''
            )
            if column['pk']:
                primary_key = column['name']
        sql += ' PRIMARY KEY (`{}`) ) ENGINE = InnoDB CHARACTER SET utf8'.format(primary_key)
        try:
            self._mysql_cur.execute(sql)
            self._mysql.commit()
        except mysql.connector.Error as err:
            print('_create_table failed creating table {}: {}'.format(table_name, err))
            exit(1)

    def transfer(self):
        self._sqlite_cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
        for row in self._sqlite_cur.fetchall():
            table = dict(row)
            # create the table
            self._create_table(table['name'])
            # populate it
            print('Transferring table {}'.format(table['name']))
            self._sqlite_cur.execute('SELECT * FROM "{}"'.format(table['name']))
            columns = [column[0] for column in self._sqlite_cur.description]
            try:
                self._mysql_cur.executemany("INSERT IGNORE INTO `{table}` ({fields}) VALUES ({placeholders})".format(
                    table=table['name'],
                    fields=('`{}`, ' * len(columns)).rstrip(' ,').format(*columns),
                    placeholders=('%s, ' * len(columns)).rstrip(' ,')
                ), (tuple(data) for data in self._sqlite_cur.fetchall()))
                self._mysql.commit()
            except mysql.connector.Error as err:
                print('_insert_table_data failed inserting data into table {}: {}'.format(table['name'], err))
                exit(1)
        print('Done!')


def main():
    """ For use in standalone terminal form """
    import sys, argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--sqlite-file', dest='sqlite_file', default=None, help='SQLite3 db file')
    parser.add_argument('--mysql-user', dest='mysql_user', default=None, help='MySQL user')
    parser.add_argument('--mysql-password', dest='mysql_password', default=None, help='MySQL password')
    parser.add_argument('--mysql-database', dest='mysql_database', default=None, help='MySQL host')
    parser.add_argument('--mysql-host', dest='mysql_host', default='localhost', help='MySQL host')
    parser.add_argument('--mysql-integer-type', dest='mysql_integer_type', default='int(11)', help='MySQL default integer field type')
    parser.add_argument('--mysql-string-type', dest='mysql_string_type', default='varchar(300)', help='MySQL default string field type')
    args = parser.parse_args()

    if len(sys.argv) == 1:
        parser.print_help()
        exit(1)

    converter = SQLite3toMySQL(
        sqlite_file=args.sqlite_file,
        mysql_user=args.mysql_user,
        mysql_password=args.mysql_password,
        mysql_database=args.mysql_database,
        mysql_host=args.mysql_host,
        mysql_integer_type=args.mysql_integer_type,
        mysql_string_type=args.mysql_string_type
    )
    converter.transfer()

if __name__ == '__main__':
    main()

0

このスクリプトは問題ありませんが、もちろん、私が会った場合を除き、問題ありません。

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)にコメントしたときにもう表示されませんでしたが、他の問題が発生しました。


    line = re.sub(r"([^'])'t'(.)", "\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')

これは特別なケースであり、「f」または「t」の値を追加したいが、正規表現にあまり慣れていない場合、このケースを見つけて誰かが修正したかっただけです。

とにかく、その便利なスクリプトに感謝します!!!


0

この簡単な解決策は私にとってうまくいきました:

<?php
$sq = new SQLite3( 'sqlite3.db' );

$tables = $sq->query( 'SELECT name FROM sqlite_master WHERE type="table"' );

while ( $table = $tables->fetchArray() ) {
    $table = current( $table );
    $result = $sq->query( sprintf( 'SELECT * FROM %s', $table ) );

    if ( strpos( $table, 'sqlite' ) !== false )
        continue;

    printf( "-- %s\n", $table );
    while ( $row = $result->fetchArray( SQLITE3_ASSOC ) ) {
        $values = array_map( function( $value ) {
            return sprintf( "'%s'", mysql_real_escape_string( $value ) );
        }, array_values( $row ) );
        printf( "INSERT INTO `%s` VALUES( %s );\n", $table, implode( ', ', $values ) );
    }
}

-5
echo ".dump" | sqlite3 /tmp/db.sqlite > db.sql

CREATEステートメントに注意する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.