7.6 KiB
7.6 KiB
Old RogDB → RogDB 移行手順書
概要
old_rogdb から rogdb へのデータ移行を行います。テーブル構造の違いにより、一部テーブルは専用スクリプトで処理します。
移行対象テーブル
通常移行(migrate_old_rogdb_to_rogdb.py)
- rog_customuser
- rog_newcategory
- rog_newevent2
- rog_member
- rog_useractions
- その他 rog_* テーブル
専用移行スクリプト
1. rog_team (migrate_rog_team_enhanced.py)
理由: 新DBで追加フィールドあり
class_name(character varying(100))event_id(bigint) - rog_newevent2への外部キーlocation(geometry(Point,4326)) - PostGIS座標password(character varying(100))trial(boolean)zekken_number(character varying(50))created_at(timestamp with time zone)updated_at(timestamp with time zone)
2. rog_entry (migrate_rog_entry_enhanced.py)
理由: camelCaseカラム名の予約語問題
hasGoaled(boolean)hasParticipated(boolean)
3. rog_goalimages (migrate_rog_goalimages_enhanced.py)
理由: team_name → zekken_number 変換ロジック
- 旧DBで
zekken_numberがブランク/NULLの場合 team_nameを使用してrog_entryから対応するzekken_numberを検索・取得- team_name → zekken_numberマッピングキャッシュを事前構築
移行手順
事前チェック
# NULL値チェック
make null-check
# カラム名チェック
make column-check
# Docker コンテナ状況確認
docker compose ps
段階的移行
ステップ1: 基本テーブル移行
# 通常テーブル移行(rog_team, rog_entry除く)
make migrate-old-rogdb
ステップ2: rog_team構造変換移行
# rog_team専用移行
make migrate-rog-team
ステップ3: rog_entry camelCase対応移行
# rog_entry専用移行
make migrate-rog-entry
ステップ4: rog_goalimages team_name変換移行
# rog_goalimages専用移行(team_name→zekken_number変換)
make migrate-rog-goalimages
一括移行
# 全テーブル一括移行
make migrate-full
外部キー依存関係
移行順序に注意が必要な依存関係:
- rog_customuser → 他テーブルのowner_id, user_id参照
- rog_newcategory → rog_team, rog_entryのcategory_id参照
- rog_newevent2 → rog_team, rog_entryのevent_id参照
- rog_team → rog_entryのteam_id参照
- rog_entry → rog_entrymemberのentry_id参照、rog_goalimadesのzekken_number解決
- rog_goalimages → rog_customuserのuser_id参照、team_name→zekken_number変換
トラブルシューティング
エラー対応
NULL値制約違反
# NULL値の詳細チェック
docker compose exec app python check_null_values.py
# 個別テーブルのNULL値確認
docker compose exec postgres-db psql -U admin -d old_rogdb -c "
SELECT column_name, COUNT(*)
FROM rog_team t, information_schema.columns c
WHERE c.table_name = 'rog_team' AND t.column_name IS NULL
GROUP BY column_name;
"
外部キー制約違反
# 参照整合性チェック
docker compose exec postgres-db psql -U admin -d old_rogdb -c "
SELECT t.team_id, COUNT(*)
FROM rog_entry t
LEFT JOIN rog_team tt ON t.team_id = tt.id
WHERE tt.id IS NULL
GROUP BY t.team_id;
"
team_name → zekken_number変換失敗
# rog_goalimagesのteam_name一覧確認
docker compose exec postgres-db psql -U admin -d old_rogdb -c "
SELECT DISTINCT team_name, zekken_number
FROM rog_goalimages
WHERE zekken_number IS NULL OR zekken_number = ''
ORDER BY team_name;
"
# 新DBでのteam_name → zekken_numberマッピング確認
docker compose exec postgres-db psql -U admin -d rogdb -c "
SELECT t.team_name, e.zekken_number
FROM rog_team t
JOIN rog_entry e ON t.id = e.team_id
ORDER BY t.team_name;
"
PostgreSQL予約語エラー
- camelCaseカラムや予約語は自動でダブルクォートで囲まれます
- エラーが発生した場合は該当スクリプトで quote_column_if_needed() を確認
ログ確認
# 移行ログのリアルタイム確認
docker compose logs -f app
# 特定期間のログ確認
docker compose logs --since="2025-08-25T08:00:00" app
設定値
環境変数
# データベース接続設定
OLD_ROGDB_HOST=postgres-db
OLD_ROGDB_NAME=old_rogdb
OLD_ROGDB_USER=admin
OLD_ROGDB_PASSWORD=admin123456
ROGDB_HOST=postgres-db
ROGDB_NAME=rogdb
ROGDB_USER=admin
ROGDB_PASSWORD=admin123456
# 除外テーブル設定(カンマ区切り)
EXCLUDE_TABLES=rog_session,django_migrations
デフォルト値設定
rog_team
trial: Falseevent_id: 最初のイベントIDlocation: NULLpassword: ''class_name: ''zekken_number: ''
rog_entry
hasGoaled: FalsehasParticipated: Falseis_active: Trueis_trial: Falsezekken_label: ''
移行後確認
データ件数確認
# テーブル別レコード数比較
docker compose exec postgres-db psql -U admin -d old_rogdb -c "
SELECT 'rog_team' as table_name, COUNT(*) as old_count FROM rog_team
UNION ALL
SELECT 'rog_entry', COUNT(*) FROM rog_entry
UNION ALL
SELECT 'rog_goalimages', COUNT(*) FROM rog_goalimages;
"
docker compose exec postgres-db psql -U admin -d rogdb -c "
SELECT 'rog_team' as table_name, COUNT(*) as new_count FROM rog_team
UNION ALL
SELECT 'rog_entry', COUNT(*) FROM rog_entry
UNION ALL
SELECT 'rog_goalimages', COUNT(*) FROM rog_goalimages;
"
制約確認
# 外部キー制約確認
docker compose exec postgres-db psql -U admin -d rogdb -c "
SELECT conname, contype
FROM pg_constraint
WHERE conrelid IN (
SELECT oid FROM pg_class WHERE relname IN ('rog_team', 'rog_entry', 'rog_goalimages')
);
"
team_name → zekken_number 変換確認
# rog_goalimadesでzekken_number変換結果確認
docker compose exec postgres-db psql -U admin -d rogdb -c "
SELECT team_name, zekken_number, COUNT(*) as count
FROM rog_goalimages
GROUP BY team_name, zekken_number
ORDER BY team_name;
"
# 変換できなかったレコード確認
docker compose exec postgres-db psql -U admin -d rogdb -c "
SELECT team_name, COUNT(*) as blank_zekken_count
FROM rog_goalimages
WHERE zekken_number IS NULL OR zekken_number = ''
GROUP BY team_name
ORDER BY blank_zekken_count DESC;
"
バックアップ・ロールバック
移行前バックアップ
# rogdbのバックアップ
docker compose exec postgres-db pg_dump -U admin rogdb > rogdb_backup_$(date +%Y%m%d_%H%M%S).sql
ロールバック
# 移行テーブルのクリア
docker compose exec postgres-db psql -U admin -d rogdb -c "
TRUNCATE rog_team, rog_entry, rog_goalimages CASCADE;
"
# バックアップからの復元
docker compose exec -T postgres-db psql -U admin -d rogdb < rogdb_backup_YYYYMMDD_HHMMSS.sql
よくある問題
- メモリ不足: docker-compose.ymlでPostgreSQLのメモリ制限を確認
- コンテナ再起動: 移行中にコンテナが再起動する場合はresources設定を調整
- 文字化け: PostgreSQLの文字エンコーディング設定確認
- タイムアウト: 大量データの場合はバッチサイズを調整
参考ファイル
docker-compose.yml: データベース設定migrate_old_rogdb_to_rogdb.py: 通常テーブル移行migrate_rog_team_enhanced.py: rog_team専用移行migrate_rog_entry_enhanced.py: rog_entry専用移行migrate_rog_goalimages_enhanced.py: rog_goalimages専用移行(team_name→zekken変換)check_null_values.py: NULL値事前チェックMakefile: 移行タスク定義