Files
rogaining_srv/migrate_fc_gifu_step_by_step.py
2025-08-29 09:11:20 +09:00

301 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
"""
old_rogdb から rogdb への段階的FC岐阜データ移行スクリプト
1. Team/Member → 2. 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
import psycopg2
print("=== old_rogdb から FC岐阜データ段階的移行 ===")
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}")
with old_conn.cursor() as old_cursor:
# === STEP 1: Team & Member データ取得 ===
print("\\n=== STEP 1: Team & Member データ取得 ===")
# FC岐阜関連のチーム情報を取得
old_cursor.execute("""
SELECT DISTINCT rt.id, rt.team_name, rt.owner_id, rt.category_id,
rc.category_name, cu.email, cu.firstname, cu.lastname
FROM rog_entry re
JOIN rog_team rt ON re.team_id = rt.id
LEFT JOIN rog_newcategory rc ON rt.category_id = rc.id
LEFT JOIN rog_customuser cu ON rt.owner_id = cu.id
WHERE re.event_id = 10
ORDER BY rt.id;
""")
team_data = old_cursor.fetchall()
print(f"FC岐阜関連チーム: {len(team_data)}")
# チームメンバー情報を取得
old_cursor.execute("""
SELECT rm.team_id, rm.user_id, cu.email, cu.firstname, cu.lastname
FROM rog_entry re
JOIN rog_member rm ON re.team_id = rm.team_id
JOIN rog_customuser cu ON rm.user_id = cu.id
WHERE re.event_id = 10
ORDER BY rm.team_id, rm.user_id;
""")
member_data = old_cursor.fetchall()
print(f"FC岐阜関連メンバー: {len(member_data)}")
# チーム別メンバー数を確認
team_member_count = {}
for team_id, user_id, email, first_name, last_name in member_data:
if team_id not in team_member_count:
team_member_count[team_id] = 0
team_member_count[team_id] += 1
print("\\nチーム別メンバー数:")
for team_id, count in team_member_count.items():
print(f" Team {team_id}: {count}")
# === STEP 2: ユーザー移行 ===
print("\\n=== STEP 2: ユーザー移行 ===")
# 関連するすべてのユーザーを取得
all_user_ids = set()
for _, _, owner_id, _, _, _, _, _ in team_data:
if owner_id:
all_user_ids.add(owner_id)
for _, user_id, _, _, _ in member_data:
all_user_ids.add(user_id)
if all_user_ids:
old_cursor.execute(f"""
SELECT id, email, firstname, lastname, date_joined
FROM rog_customuser
WHERE id IN ({','.join(map(str, all_user_ids))})
""")
user_data = old_cursor.fetchall()
print(f"移行対象ユーザー: {len(user_data)}")
migrated_users = 0
for user_id, email, first_name, last_name, date_joined in user_data:
user, created = CustomUser.objects.get_or_create(
id=user_id,
defaults={
'email': email or f'user{user_id}@example.com',
'first_name': first_name or '',
'last_name': last_name or '',
'username': email or f'user{user_id}',
'date_joined': date_joined,
'is_active': True
}
)
if created:
migrated_users += 1
print(f" ユーザー作成: {email} ({first_name} {last_name})")
print(f"✅ ユーザー移行完了: {migrated_users}件作成")
# === STEP 3: カテゴリ移行 ===
print("\\n=== STEP 3: カテゴリ移行 ===")
migrated_categories = 0
for _, _, _, cat_id, cat_name, _, _, _ in team_data:
if cat_id and cat_name:
category, created = NewCategory.objects.get_or_create(
id=cat_id,
defaults={
'category_name': cat_name,
'category_number': cat_id
}
)
if created:
migrated_categories += 1
print(f" カテゴリ作成: {cat_name}")
print(f"✅ カテゴリ移行完了: {migrated_categories}件作成")
# === STEP 4: チーム移行 ===
print("\\n=== STEP 4: チーム移行 ===")
migrated_teams = 0
for team_id, team_name, owner_id, cat_id, cat_name, email, first_name, last_name in team_data:
try:
# カテゴリを取得
category = NewCategory.objects.get(id=cat_id) if cat_id else None
# チームを作成
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
}
)
if created:
migrated_teams += 1
print(f" チーム作成: {team_name} (ID: {team_id})")
except Exception as e:
print(f" ❌ チーム作成エラー: {team_name} - {e}")
print(f"✅ チーム移行完了: {migrated_teams}件作成")
# === STEP 5: メンバー移行 ===
print("\\n=== STEP 5: メンバー移行 ===")
migrated_members = 0
for team_id, user_id, email, first_name, last_name in member_data:
try:
# チームとユーザーを取得
team = Team.objects.get(id=team_id)
user = CustomUser.objects.get(id=user_id)
# メンバーを作成
member, created = Member.objects.get_or_create(
team=team,
user=user
)
if created:
migrated_members += 1
print(f" メンバー追加: {email}{team.team_name}")
except Team.DoesNotExist:
print(f" ⚠️ チーム{team_id}が見つかりません")
except CustomUser.DoesNotExist:
print(f" ⚠️ ユーザー{user_id}が見つかりません")
except Exception as e:
print(f" ❌ メンバー追加エラー: {e}")
print(f"✅ メンバー移行完了: {migrated_members}件作成")
# === STEP 6: エントリー移行 ===
print("\\n=== STEP 6: エントリー移行 ===")
# まず、現在のDBのis_trialフィールドにデフォルト値を設定
print("データベーステーブルのis_trialフィールドを修正中...")
from django.db import connection as django_conn
with django_conn.cursor() as django_cursor:
try:
# is_trialフィールドにデフォルト値を設定
django_cursor.execute("""
ALTER TABLE rog_entry
ALTER COLUMN is_trial SET DEFAULT FALSE;
""")
print(" ✅ is_trialフィールドにデフォルト値を設定")
except Exception as e:
print(f" ⚠️ is_trial修正エラー: {e}")
# FC岐阜エントリーデータを取得
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()
migrated_entries = 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 = NewCategory.objects.get(id=cat_id) if cat_id else None
# まず既存のエントリーをチェック
existing_entry = Entry.objects.filter(team=team, event=fc_event).first()
if existing_entry:
print(f" 🔄 既存エントリー: {team_name} - ゼッケン{existing_entry.zekken_number}")
continue
# SQLで直接エントリーを挿入
from django.db import connection as django_conn
with django_conn.cursor() as django_cursor:
django_cursor.execute("""
INSERT INTO rog_entry
(date, category_id, event_id, owner_id, team_id, is_active,
zekken_number, "hasGoaled", "hasParticipated", zekken_label,
is_trial, staff_privileges, can_access_private_events, team_validation_status)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);
""", [
fc_event.start_datetime, # date
cat_id, # category_id
fc_event.id, # event_id
owner_id or 1, # owner_id
team_id, # team_id
True, # is_active
int(zekken) if zekken else 0, # zekken_number
False, # hasGoaled
False, # hasParticipated
label or f"FC岐阜-{zekken}", # zekken_label
False, # is_trial
False, # staff_privileges
False, # can_access_private_events
'approved' # team_validation_status
])
migrated_entries += 1
print(f" ✅ エントリー作成: {team_name} - ゼッケン{zekken}")
except Team.DoesNotExist:
print(f" ❌ チーム{team_id}が見つかりません: {team_name}")
except Exception as e:
print(f" ❌ エントリー作成エラー: {team_name} - {e}")
print(f"✅ エントリー移行完了: {migrated_entries}件作成")
old_conn.close()
# === 最終確認 ===
print("\\n=== 移行結果確認 ===")
fc_entries = Entry.objects.filter(event=fc_event).order_by('zekken_number')
print(f"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}")
print("\\n🎉 FC岐阜イベントのゼッケン番号表示問題が解決されました")
print("\\n🎯 通過審査管理画面でFC岐阜を選択すると、ゼッケン番号が表示されるようになります。")
else:
print("❌ エントリーデータの移行に失敗しました")
except Exception as e:
print(f"❌ エラーが発生しました: {e}")
import traceback
traceback.print_exc()