#!/usr/bin/env python """ old_rogdb から rogdb への包括的FC岐阜データ移行スクリプト Team → Member → Entry の順序で移行 """ import os import sys import django if __name__ == '__main__': os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') django.setup() from django.db import transaction from rog.models import NewEvent2, Team, Entry, NewCategory, CustomUser, Member from datetime import datetime import psycopg2 print("=== FC岐阜包括データ移行(Team→Member→Entry順序)===") try: # old_rogdbに直接接続 old_conn = psycopg2.connect( host='postgres-db', database='old_rogdb', user='admin', password='admin123456' ) print("✅ old_rogdbに接続成功") # FC岐阜イベントを確認 fc_event = NewEvent2.objects.filter(id=10).first() if not fc_event: print("❌ FC岐阜イベント(ID:10)が見つかりません") old_conn.close() sys.exit(1) print(f"✅ FC岐阜イベント: {fc_event.event_name}") print(f" 期間: {fc_event.start_datetime} - {fc_event.end_datetime}") with old_conn.cursor() as old_cursor: # Step 1: FC岐阜のチームデータを取得・移行 print("\\n=== Step 1: チーム移行 ===") old_cursor.execute(""" SELECT DISTINCT rt.id, rt.team_name, rt.owner_id, rt.category_id, rc.category_name, rt.password, rt.trial FROM rog_team rt JOIN rog_entry re ON rt.id = re.team_id LEFT JOIN rog_newcategory rc ON rt.category_id = rc.id WHERE re.event_id = 10 ORDER BY rt.id; """) team_data = old_cursor.fetchall() print(f"FC岐阜関連チーム: {len(team_data)}件") team_created_count = 0 team_errors = 0 for team_id, team_name, owner_id, cat_id, cat_name, password, trial in team_data: try: # カテゴリを取得または作成 category = None if cat_id and cat_name: category, cat_created = NewCategory.objects.get_or_create( id=cat_id, defaults={ 'category_name': cat_name, 'category_number': cat_id } ) if cat_created: print(f" カテゴリ作成: {cat_name}") # チームを作成(メンバー制約を一時的に無視) team, team_created = Team.objects.get_or_create( id=team_id, defaults={ 'team_name': team_name, 'owner_id': owner_id or 1, 'category': category, 'event_id': fc_event.id, 'password': password or '', 'trial': trial or False } ) if team_created: print(f" ✅ チーム作成: {team_name} (ID: {team_id})") team_created_count += 1 else: print(f" 🔄 既存チーム: {team_name} (ID: {team_id})") except Exception as e: team_errors += 1 print(f" ❌ チームエラー: {team_name} - {e}") # Step 2: メンバーデータを取得・移行 print(f"\\n=== Step 2: メンバー移行 ===") old_cursor.execute(""" SELECT rm.id, rm.team_id, rm.user_id, cu.firstname, cu.lastname, cu.email FROM rog_member rm JOIN rog_team rt ON rm.team_id = rt.id JOIN rog_entry re ON rt.id = re.team_id LEFT JOIN rog_customuser cu ON rm.user_id = cu.id WHERE re.event_id = 10 ORDER BY rm.team_id, rm.id; """) member_data = old_cursor.fetchall() print(f"FC岐阜関連メンバー: {len(member_data)}件") member_created_count = 0 member_errors = 0 for member_id, team_id, user_id, firstname, lastname, email in member_data: try: # チームを取得 team = Team.objects.get(id=team_id) # ユーザーを取得または作成 user = None if user_id: try: user = CustomUser.objects.get(id=user_id) except CustomUser.DoesNotExist: # ユーザーが存在しない場合は作成 user = CustomUser.objects.create( id=user_id, email=email or f"user{user_id}@example.com", firstname=firstname or "名前", lastname=lastname or "苗字", is_active=True ) print(f" ユーザー作成: {firstname} {lastname}") # メンバーを作成 member, member_created = Member.objects.get_or_create( team=team, user=user, defaults={} ) if member_created: print(f" ✅ メンバー作成: {firstname} {lastname} -> {team.team_name}") member_created_count += 1 else: print(f" 🔄 既存メンバー: {firstname} {lastname} -> {team.team_name}") except Team.DoesNotExist: print(f" ⚠️ チーム{team_id}が見つかりません") except Exception as e: member_errors += 1 print(f" ❌ メンバーエラー: {firstname} {lastname} - {e}") # Step 3: エントリーデータを移行 print(f"\\n=== Step 3: エントリー移行 ===") old_cursor.execute(""" SELECT re.id, re.team_id, re.zekken_number, re.zekken_label, rt.team_name, re.category_id, re.date, re.owner_id, rc.category_name FROM rog_entry re JOIN rog_team rt ON re.team_id = rt.id LEFT JOIN rog_newcategory rc ON re.category_id = rc.id WHERE re.event_id = 10 ORDER BY re.zekken_number; """) entry_data = old_cursor.fetchall() print(f"FC岐阜エントリー: {len(entry_data)}件") entry_created_count = 0 entry_errors = 0 for entry_id, team_id, zekken, label, team_name, cat_id, date, owner_id, cat_name in entry_data: try: # チームを取得 team = Team.objects.get(id=team_id) # カテゴリを取得 category = None if cat_id: try: category = NewCategory.objects.get(id=cat_id) except NewCategory.DoesNotExist: pass # 日時を調整(イベント期間内に設定) entry_date = fc_event.start_datetime if date: try: # 既存の日付がイベント期間内かチェック if fc_event.start_datetime.date() <= date.date() <= fc_event.end_datetime.date(): entry_date = date except: pass # エントリーを作成 entry, entry_created = Entry.objects.get_or_create( team=team, event=fc_event, defaults={ 'category': category, 'date': entry_date, 'owner_id': owner_id or 1, 'zekken_number': int(zekken) if zekken else 0, 'zekken_label': label or f"FC岐阜-{zekken}", 'is_active': True, 'hasParticipated': False, 'hasGoaled': False } ) if entry_created: print(f" ✅ エントリー作成: {team_name} - ゼッケン{zekken}") entry_created_count += 1 else: print(f" 🔄 既存エントリー: {team_name} - ゼッケン{zekken}") except Team.DoesNotExist: print(f" ⚠️ チーム{team_id}が見つかりません: {team_name}") entry_errors += 1 except Exception as e: entry_errors += 1 print(f" ❌ エントリーエラー: {team_name} - {e}") old_conn.close() print(f"\\n=== 移行完了統計 ===") print(f"チーム作成: {team_created_count}件 (エラー: {team_errors}件)") print(f"メンバー作成: {member_created_count}件 (エラー: {member_errors}件)") print(f"エントリー作成: {entry_created_count}件 (エラー: {entry_errors}件)") # 最終確認 fc_entries = Entry.objects.filter(event=fc_event).order_by('zekken_number') print(f"\\n🎉 FC岐阜イベント総エントリー: {fc_entries.count()}件") if fc_entries.exists(): print("\\nゼッケン番号一覧(最初の10件):") for entry in fc_entries[:10]: print(f" ゼッケン{entry.zekken_number}: {entry.team.team_name}") if fc_entries.count() > 10: print(f" ... 他 {fc_entries.count() - 10}件") print("\\n🎉 FC岐阜イベントのゼッケン番号表示問題が解決されました!") print("🎯 通過審査管理画面でFC岐阜を選択すると、参加者のゼッケン番号が表示されるようになります。") else: print("❌ エントリーが作成されませんでした") except Exception as e: print(f"❌ エラーが発生しました: {e}") import traceback traceback.print_exc()