294 lines
7.6 KiB
Markdown
294 lines
7.6 KiB
Markdown
|
|
# 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マッピングキャッシュを事前構築
|
|||
|
|
|
|||
|
|
## 移行手順
|
|||
|
|
|
|||
|
|
### 事前チェック
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# NULL値チェック
|
|||
|
|
make null-check
|
|||
|
|
|
|||
|
|
# カラム名チェック
|
|||
|
|
make column-check
|
|||
|
|
|
|||
|
|
# Docker コンテナ状況確認
|
|||
|
|
docker compose ps
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 段階的移行
|
|||
|
|
|
|||
|
|
#### ステップ1: 基本テーブル移行
|
|||
|
|
```bash
|
|||
|
|
# 通常テーブル移行(rog_team, rog_entry除く)
|
|||
|
|
make migrate-old-rogdb
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### ステップ2: rog_team構造変換移行
|
|||
|
|
```bash
|
|||
|
|
# rog_team専用移行
|
|||
|
|
make migrate-rog-team
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### ステップ3: rog_entry camelCase対応移行
|
|||
|
|
```bash
|
|||
|
|
# rog_entry専用移行
|
|||
|
|
make migrate-rog-entry
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### ステップ4: rog_goalimages team_name変換移行
|
|||
|
|
```bash
|
|||
|
|
# rog_goalimages専用移行(team_name→zekken_number変換)
|
|||
|
|
make migrate-rog-goalimages
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 一括移行
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 全テーブル一括移行
|
|||
|
|
make migrate-full
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 外部キー依存関係
|
|||
|
|
|
|||
|
|
移行順序に注意が必要な依存関係:
|
|||
|
|
|
|||
|
|
1. **rog_customuser** → 他テーブルのowner_id, user_id参照
|
|||
|
|
2. **rog_newcategory** → rog_team, rog_entryのcategory_id参照
|
|||
|
|
3. **rog_newevent2** → rog_team, rog_entryのevent_id参照
|
|||
|
|
4. **rog_team** → rog_entryのteam_id参照
|
|||
|
|
5. **rog_entry** → rog_entrymemberのentry_id参照、rog_goalimadesのzekken_number解決
|
|||
|
|
6. **rog_goalimages** → rog_customuserのuser_id参照、team_name→zekken_number変換
|
|||
|
|
|
|||
|
|
## トラブルシューティング
|
|||
|
|
|
|||
|
|
### エラー対応
|
|||
|
|
|
|||
|
|
#### NULL値制約違反
|
|||
|
|
```bash
|
|||
|
|
# 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;
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 外部キー制約違反
|
|||
|
|
```bash
|
|||
|
|
# 参照整合性チェック
|
|||
|
|
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変換失敗
|
|||
|
|
```bash
|
|||
|
|
# 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() を確認
|
|||
|
|
|
|||
|
|
### ログ確認
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 移行ログのリアルタイム確認
|
|||
|
|
docker compose logs -f app
|
|||
|
|
|
|||
|
|
# 特定期間のログ確認
|
|||
|
|
docker compose logs --since="2025-08-25T08:00:00" app
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 設定値
|
|||
|
|
|
|||
|
|
### 環境変数
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# データベース接続設定
|
|||
|
|
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`: False
|
|||
|
|
- `event_id`: 最初のイベントID
|
|||
|
|
- `location`: NULL
|
|||
|
|
- `password`: ''
|
|||
|
|
- `class_name`: ''
|
|||
|
|
- `zekken_number`: ''
|
|||
|
|
|
|||
|
|
#### rog_entry
|
|||
|
|
- `hasGoaled`: False
|
|||
|
|
- `hasParticipated`: False
|
|||
|
|
- `is_active`: True
|
|||
|
|
- `is_trial`: False
|
|||
|
|
- `zekken_label`: ''
|
|||
|
|
|
|||
|
|
## 移行後確認
|
|||
|
|
|
|||
|
|
### データ件数確認
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# テーブル別レコード数比較
|
|||
|
|
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;
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 制約確認
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 外部キー制約確認
|
|||
|
|
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 変換確認
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 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;
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## バックアップ・ロールバック
|
|||
|
|
|
|||
|
|
### 移行前バックアップ
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# rogdbのバックアップ
|
|||
|
|
docker compose exec postgres-db pg_dump -U admin rogdb > rogdb_backup_$(date +%Y%m%d_%H%M%S).sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ロールバック
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 移行テーブルのクリア
|
|||
|
|
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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## よくある問題
|
|||
|
|
|
|||
|
|
1. **メモリ不足**: docker-compose.ymlでPostgreSQLのメモリ制限を確認
|
|||
|
|
2. **コンテナ再起動**: 移行中にコンテナが再起動する場合はresources設定を調整
|
|||
|
|
3. **文字化け**: PostgreSQLの文字エンコーディング設定確認
|
|||
|
|
4. **タイムアウト**: 大量データの場合はバッチサイズを調整
|
|||
|
|
|
|||
|
|
## 参考ファイル
|
|||
|
|
|
|||
|
|
- `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`: 移行タスク定義
|