Быстрый простой способ перенести SQLite3 на MySQL? [закрыто]

Кто-нибудь знает быстрый и простой способ переноса базы данных SQLite3 в MySQL?

20.08.2008 19:49:13
17 ОТВЕТОВ
РЕШЕНИЕ

Вот список конвертеров (не обновляется с 2011 года):


Альтернативный метод, который будет работать хорошо, но редко упоминается: используйте класс ORM, который абстрагирует вас от конкретных различий в базе данных. например, вы получаете их в PHP ( RedBean ), Python (слой ORM Джанго, Storm , SqlAlchemy ), Ruby on Rails ( ActiveRecord ), какао ( CoreData )

то есть вы могли бы сделать это:

  1. Загрузка данных из исходной базы данных с использованием класса ORM.
  2. Храните данные в памяти или сериализуйте на диск.
  3. Сохраните данные в целевой базе данных, используя класс ORM.
60
15.08.2019 15:35:40

Недавно мне пришлось перейти с MySQL на JavaDB для проекта, над которым работает наша команда. Я нашел библиотеку Java, написанную Apache под названием DdlUtils, которая сделала это довольно легко. Он предоставляет API, который позволяет вам делать следующее:

  1. Найдите схему базы данных и экспортируйте ее в файл XML.
  2. Изменить БД на основе этой схемы.
  3. Импортируйте записи из одной БД в другую, предполагая, что они имеют одинаковую схему.

Инструменты, с которыми мы работали, не были полностью автоматизированы, но они работали довольно хорошо. Даже если ваше приложение не на Java, не должно быть слишком сложно собрать несколько небольших инструментов для одноразовой миграции. Я думаю, что я смог вытащить нашу миграцию с менее чем 150 строками кода.

5
21.08.2008 03:12:51

Вероятно, самый простой способ - использовать команду sqlite .dump, в этом случае создайте дамп образца базы данных.

sqlite3 sample.db .dump > dump.sql

Затем вы можете (теоретически) импортировать это в базу данных mysql, в данном случае тестовую базу данных на сервере базы данных 127.0.0.1, используя пользователя root.

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

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

В sqlite начинаются транзакции

BEGIN TRANSACTION;
...
COMMIT;

MySQL использует только

BEGIN;
...
COMMIT;

Есть и другие подобные проблемы (всплывают varchars и двойные кавычки), но ничего найти и заменить не удалось исправить.

Возможно, вам следует спросить, почему вы мигрируете, если проблема заключается в производительности / размере базы данных, возможно, стоит взглянуть на переопределение схемы, если система переходит на более мощный продукт, это может быть идеальным временем для планирования будущего ваших данных.

10
25.08.2008 11:10:04
но наиболее трудной задачей является разница betweek грамматик
francois 27.07.2012 23:30:01

Кажется, что все начинают с нескольких выражений grep и perl, и вы вроде бы получаете что-то, что работает для вашего конкретного набора данных, но вы не представляете, правильно ли он импортировал данные или нет. Я серьезно удивлен, что никто не создал надежную библиотеку, которая может конвертировать между ними.

Вот список ВСЕХ различий в синтаксисе SQL, о которых я знаю между двумя форматами файлов: Строки, начинающиеся с:

  • НАЧАЛО СДЕЛКИ
  • COMMIT
  • 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 использует 1и 0(простое регулярное выражение для этого может потерпеть неудачу, если у вас есть строка вроде: «Я делаю, вы не 'внутри» INSERT INTO)
  • SQLLite использует AUTOINCREMENT, MySQL используетAUTO_INCREMENT

Вот очень простой взломанный скрипт на Perl, который работает для моего набора данных и проверяет многие из этих условий, которые встречаются в других скриптах на Perl, которые я нашел в сети. Мы гарантируем, что это сработает для ваших данных, но вы можете изменить их и опубликовать здесь.

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){

        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/){
            $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_]*)\"(.*)/){
            $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;
    }
}
107
26.02.2019 08:30:29
Алекс Мартелли проделал отличную работу, переписав это как python на stackoverflow.com/questions/1067060/perl-to-python
Jiaaro 1.07.2009 03:38:05
Я добавил полный скрипт на python (сам скрипт perl не совсем работал для меня ... нужна дополнительная обработка для обработки внешних ключей и индексов)
Jiaaro 1.07.2009 05:11:31
Я переписал этот ответ на другой вопрос stackoverflow.com/questions/1067060/_/1070463#1070463
Brad Gilbert 26.08.2009 14:51:36
COMMIT и CREATE UNIQUE INDEX являются действительными командами MySQL, пожалуйста, исправьте это.
niutech 6.06.2013 09:49:23
Я понимаю, что ваш скрипт "быстрый и грязный", но также очень полезный, поэтому вот несколько дополнений / исправлений: * после && ($line !~ /CREATE UNIQUE INDEX/)добавления && ($line !~ /PRAGMA foreign_keys=OFF/) * регулярное выражение для сопоставления имен таблиц пропускает цифры, то есть вместо $line =~ /INSERT INTO \"([a-z_]*)\"(.*)/этого должен быть $line =~ /INSERT INTO \"([a-z_1-9]*)\"(.*)/ Надеюсь, что это поможет будущему читатели
Michał Leon 30.01.2014 22:01:53

Вот скрипт на python, построенный на ответе Шалманеса и некоторой помощи от Алекса Мартелли из Translating Perl to Python.

Я делаю это вики-сообществом, поэтому, пожалуйста, не стесняйтесь редактировать и рефакторинг, если он не нарушает функциональность (к счастью, мы можем просто откатиться) - Это довольно уродливо, но работает

использовать так (при условии, что скрипт называется 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,
49
23.05.2017 11:47:28
Привет, Джим, в моем наборе данных каждое первое выражение INSERT заключено в обратную кавычку вместо одной кавычки: __ DROP TABLE IF EXISTS schema_migrations; СОЗДАЙТЕ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ schema_migrations( versionvarchar (255) NOT NULL); INSERT INTO schema_migrations VALUES ( 20100714032840); INSERT INTO schema_migrations VALUES ('20100714033251'); ___
David 5.08.2010 02:26:53
хорошо ... это не показывается выше, но обратные кавычки появляются внутри ЗНАЧЕНИЙ ([ЗДЕСЬ] 20100714032840 [/ ЗДЕСЬ])
David 5.08.2010 02:28:17
AUTOINCREMENT в Mysql - это AUTO_INCREMENT. Сценарий не учитывает это.
giuseppe 27.09.2013 08:01:14
Это не работает для базы данных медиа вики. Много ошибок: Blobvarтип данных, обратные тики в операторе CREATE ...
Frank Hintsch 10.09.2017 18:32:28
не работает Может быть, не все условия принимаются во внимание ...
Himanshu Bansal 9.11.2017 09:29:32

Этот сценарий в порядке, за исключением этого случая, который, конечно, я встречал:

INSERT INTO VALUES "requestcomparison_stopword" (149, 'f');
INSERT INTO VALUES "requestcomparison_stopword" (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;

с некоторыми странными не-ascii символами вокруг последних 0 и 1.

Это больше не проявилось, когда я прокомментировал следующие строки кода (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
30.09.2009 14:50:54

Ха ... Хотел бы я найти это первым! Мой ответ был на этот пост ... скрипт для конвертирования файла sql mysql dump в формат, который можно импортировать в sqlite3 db

Объединение двух было бы именно тем, что мне было нужно:


Когда база данных 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
23.05.2017 12:26:27

На основе решения 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, чтобы выбросить эту строку.

3
23.05.2017 12:02:48
У меня были некоторые проблемы с кодировкой UTF-8 с импортированными данными, но добавление --default-character-set = utf8 к команде импорта, похоже, исправило это. Взято из этого Q / A: stackoverflow.com/questions/346092/…
Snips 13.11.2012 00:09:53
Хорошо, я добавил это - это нормально?
alekwisnia 13.11.2012 11:55:45
Вот где я использую дополнительный переключатель, да.
Snips 13.11.2012 12:01:27
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
8
12.10.2011 22:07:08
echo ".dump" | sqlite3 /tmp/db.sqlite > db.sql

следите за заявлениями CREATE

-5
26.10.2012 10:12:06

Я только что прошел этот процесс, и в этом Q / A есть много очень хорошей помощи и информации, но я обнаружил, что мне нужно было собрать воедино различные элементы (плюс некоторые из других Q / As), чтобы получить рабочее решение в Чтобы успешно мигрировать.

Однако даже после объединения существующих ответов я обнаружил, что сценарий Python не работает для меня полностью, так как он не работает там, где в INSERT было многократное логическое вхождение. Смотрите здесь, почему это так.

Итак, я решил опубликовать свой объединенный ответ здесь. Конечно, это заслуга тех, кто внес свой вклад в другом месте. Но я хотел что-то вернуть и сэкономить время другим.

Я выложу сценарий ниже. Но во-первых, вот инструкция для преобразования ...

Я запустил скрипт на OS X 10.7.5 Lion. Python работал из коробки.

Чтобы сгенерировать входной файл MySQL из существующей базы данных SQLite3, запустите сценарий для своих файлов следующим образом:

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

Затем я скопировал полученный файл dumped_sql.sql в Linux-систему с Ubuntu 10.04.4 LTS, где должна была находиться моя база данных MySQL.

Еще одна проблема, с которой я столкнулся при импорте файла 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

Пусть готовит, и так и должно быть! Не забудьте внимательно изучить ваши данные до и после.

Так что, по требованию ОП, это легко и быстро, когда вы знаете, как! :-)

Кроме того, одна вещь, в которой я не был уверен, прежде чем изучать эту миграцию, заключалась в том, будут ли сохранены значения полей create_at и updated_at - для меня хорошая новость заключается в том, что они есть, поэтому я мог перенести существующие производственные данные.

Удачи!

ОБНОВИТЬ

С тех пор как я переключился, я заметил проблему, которую раньше не замечал. В моем приложении на Rails мои текстовые поля определены как «строка», и это распространяется на схему базы данных. Описанный здесь процесс приводит к тому, что они определяются как VARCHAR (255) в базе данных MySQL. Это накладывает ограничение на 255 символов для этих размеров полей - и все, что за этим было молча усечено во время импорта. Я считаю, что для поддержки длины текста, превышающей 255, в схеме MySQL нужно будет использовать 'TEXT', а не VARCHAR (255). Процесс, определенный здесь, не включает это преобразование.


Вот объединенный и переработанный скрипт 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,
7
23.05.2017 12:02:48
Спасибо. Сценарий, как написано выше, содержит синтаксическую ошибку; «else:» в строке 41 не соответствует нужному уровню отступа. Мне не ясно, должны ли строки над ним быть с отступом или что-то еще происходит. Хотите обновить?
Dan Tenenbaum 25.08.2015 23:00:32

Получить дамп 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 дает вам индикатор выполнения:

введите описание изображения здесь

3
22.06.2013 11:36:51
Это не работает из-за небольших различий в синтаксисе и флагов в sqlite против mysql. Вам все еще нужно вручную конвертировать его.
dlite922 25.02.2014 18:59:57

Я написал этот простой скрипт на 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()
1
21.12.2019 07:28:58

Это простое решение сработало для меня:

<?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 ) );
    }
}
0
19.11.2015 06:41:00

Нет необходимости ни в каком скрипте, команде и т.д ...

вам нужно только экспортировать базу данных sqlite в виде .csvфайла, а затем импортировать ее в Mysql с помощью phpmyadmin.

Я использовал его, и он работал потрясающе ...

4
16.07.2016 18:54:15
В сочетании с этим , это единственный ответ, который работал для меня.
cdauth 17.01.2017 14:07:11

Если вы используете Python / Django, это довольно просто:

создайте две базы данных в settings.py (как здесь https://docs.djangoproject.com/en/1.11/topics/db/multi-db/ )

тогда просто сделайте так:

objlist = ModelObject.objects.using('sqlite').all()

for obj in objlist:
    obj.save(using='mysql')
8
12.07.2017 15:32:34

Я обычно использую функцию экспорта / импорта таблиц IntelliJ DataGrip .

шаг 1 шаг 2 шаг 3

Вы можете увидеть прогресс в правом нижнем углу.

[ введите описание изображения здесь]

5
16.10.2018 16:33:01