Fix migration error
This commit is contained in:
300
migrate_fc_gifu_step_by_step.py
Normal file
300
migrate_fc_gifu_step_by_step.py
Normal file
@ -0,0 +1,300 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user