Я только что прошел этот процесс, и в этой 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 - для меня хорошая новость заключается в том, что они есть, поэтому я мог перенести свою существующую продукцию. данные.
Удачи!
UPDATE
С момента включения этого переключателя я заметил проблему, которую раньше не замечал. В моем приложении на 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,