Djangoプロジェクトにおけるデータベース移行とデータ移行の実践的手順

はじめに

Django開発では、初期段階でSQLiteが標準的に使用されますが、本番環境への展開時にはMySQLやPostgreSQLなどの本格的なRDBMSへ移行することが一般的です。このとき、スキーマだけでなくデータの整合性を保ちながらの移行が課題となります。本稿では、Djangoの機能を活用して安全かつ確実にデータベースを切り替える手順を解説します。

基本的な移行プロセス

以下の手順でデータベースの変更を行います。

  1. 現在のデータをエクスポート: Djangoのdumpdataコマンドを使用して、全モデルのデータをJSON形式で出力します。
  2. 新しいデータベースの準備: MySQLやPostgreSQL上に空のデータベースを作成します。
  3. 設定ファイルの更新: settings.py内のDATABASES設定を新しいデータベース向けに変更します。
  4. マイグレーションの適用: migrateコマンドを実行し、テーブル構造を再作成します。
  5. データのインポート: 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

この方法なら、途中で失敗しても特定のモデルのみ再実行可能です。

タグ: Django データベース移行 PostgreSQL MySQL データ移行

9月17日 23:14 投稿