はじめに
個人プロダクトでDjangoを扱っていて、デフォルトのままSQLite3で作業していたのですが、そろそろMySQLに移行しようかなぁと思っていつも通り、以下のコマンドを使って操作した場合、エラーがでてよくわからないまま対処できなかったのでメモ的な
$ python manage.py dumpdata --indent 4 > dump.json
# Databaseの向き先を変更する
$ python manage.py loaddata dump.json
環境
- Django 1.10.5
- mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64)
- Python 3.6.x
SQLite3からデータをdumpする
$ sqlite3 db.sqlite3 .dump > dump.sql
または
$ sqlite3 db.sqlite3
sqlite> .output ./dump.sql
sqlite> .dump
これで dump.sql
といったようなファイルが指定したディレクトリにできたはず。
SQLite3用のSQLデータをMySQLでも使えるようにコンバート
このままではMySQLでは使えないのでコンバートする必要があります。
Redmineさんがいい感じなのを用意してくださってました!感謝!!
と思っていたのですが、スクリプト自体はPython2のみの対応。
といっても print
がPython3に対応していないだけっぽいのでちょっと書き換え。
sqlite3-to-mysql.py
#! /usr/bin/env python
import sys
def main():
print("SET sql_mode='NO_BACKSLASH_ESCAPES';")
lines = sys.stdin.read().splitlines()
for line in lines:
processLine(line)
def processLine(line):
if (
line.startswith("PRAGMA") or
line.startswith("BEGIN TRANSACTION;") or
line.startswith("COMMIT;") or
line.startswith("DELETE FROM sqlite_sequence;") or
line.startswith("INSERT INTO \"sqlite_sequence\"")
):
return
line = line.replace("AUTOINCREMENT", "AUTO_INCREMENT")
line = line.replace("DEFAULT 't'", "DEFAULT '1'")
line = line.replace("DEFAULT 'f'", "DEFAULT '0'")
line = line.replace(",'t'", ",'1'")
line = line.replace(",'f'", ",'0'")
in_string = False
newLine = ''
for c in line:
if not in_string:
if c == "'":
in_string = True
elif c == '"':
newLine = newLine + '`'
continue
elif c == "'":
in_string = False
newLine = newLine + c
print(newLine)
if __name__ == "__main__":
main()
変えたのは print
の文法のみ。Python2, 3の違いを知っていれば問題のない問題
コンバート
$ cat dump.sql | python sqlite3-to-mysql.py > mysql.sql
みたいな感じにすると mysql.sql
と言ったやつができているはず。
MySQLに入れる
$ mysql -u USERNAME -p
mysql> CREATE DATABASE hoge CHARACTER SET utf8mb4;
mysql> USE hoge;
mysql> source /path/to/mysql.sql;
最後に
注意として特殊文字(絵文字等)はどうやらいい感じにコンバート後のインポートが上手く行かないのでそういうのが対処されてなくてもいいやっていう方は実践されてみてはいかかがでしょうか?