はじめに
Django開発では、初期段階でSQLiteが標準的に使用されますが、本番環境への展開時にはMySQLやPostgreSQLなどの本格的なRDBMSへ移行することが一般的です。このとき、スキーマだけでなくデータの整合性を保ちながらの移行が課題となります。本稿では、Djangoの機能を活用して安全かつ確実にデータベースを切り替える手順を解説します。
基本的な移行プロセス
以下の手順でデータベースの変更を行います。
- 現在のデータをエクスポート: Djangoの
dumpdataコマンドを使用して、全モデルのデータをJSON形式で出力します。 - 新しいデータベースの準備: MySQLやPostgreSQL上に空のデータベースを作成します。
- 設定ファイルの更新:
settings.py内のDATABASES設定を新しいデータベース向けに変更します。 - マイグレーションの適用:
migrateコマンドを実行し、テーブル構造を再作成します。 - データのインポート:
loaddataコマンドで先ほどエクスポートしたJSONファイルを読み込みます。
データベース接続設定の例
import os
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'myproject_db',
'USER': 'dbuser',
'PASSWORD': 'securepassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
PostgreSQLを利用する場合はpsycopg2、MySQLの場合はmysqlclientパッケージを事前にインストールしてください。
エクスポート時のエンコーディング問題
日本語や特殊文字を含むデータを扱う場合、次のようなエラーが発生することがあります。
CommandError: Unable to serialize database: 'gbk' codec can't encode character '\u30fb'
これを回避するには、PythonのUTF-8モードを有効にしてエクスポートを行います。
python -X utf8 manage.py dumpdata --exclude auth.permission --exclude contenttypes.contenttype > backup.json
auth.permissionとcontenttypesはマイグレーション時に自動生成されるため、除外することで重複エラーを防げます。
インポート時の主なエラー対策
1. 主キー・一意制約の重複(IntegrityError)
特にContentTypeやPermissionで発生しやすいです。解決策は以下の通りです。
方法A:ナチュラルキーを使用したダンプ
関連オブジェクトの参照を自然キーで表現することで、IDの衝突を回避できます。
python -X utf8 manage.py dumpdata --natural-foreign --natural-primary > backup.json
方法B:ContentTypesのクリア
既存のコンテンツタイプを削除してからインポートします。
python manage.py shell
>>> from django.contrib.contenttypes.models import ContentType
>>> ContentType.objects.all().delete()
2. 文字コードデコードエラー
次のようなエラーが発生した場合:
UnicodeDecodeError: 'utf-8' codec can’t decode byte 0xff in position 0
インポート時にもUTF-8モードを明示的に指定します。
python -X utf8 manage.py loaddata backup.json
これにより、内部エンコーディング処理が強制的にUTF-8として扱われ、多くのエンコード問題を回避できます。
補足:大規模データへの対応
数百万レコードを超えるような大規模データセットの場合、単一のJSONファイルではメモリ不足になる可能性があります。その際は、アプリケーションごとに分割してダンプ・ロードすることを推奨します。
python -X utf8 manage.py dumpdata myapp.MyModel > mymodel_data.json
python manage.py loaddata mymodel_data.json
この方法なら、途中で失敗しても特定のモデルのみ再実行可能です。