diff --git a/migrate_rog_team_enhanced.py b/migrate_rog_team_enhanced.py index c91795b..b93d966 100644 --- a/migrate_rog_team_enhanced.py +++ b/migrate_rog_team_enhanced.py @@ -76,6 +76,35 @@ class RogTeamMigrator: except Exception as e: logger.warning(f"接続クローズ時の警告: {e}") + def get_team_zekken_and_event(self, team_id): + """team_idから最新のrog_entryのzekken_numberとevent_idを取得""" + try: + # 旧DBのrog_entryから該当team_idの最新レコードを取得 + self.old_cursor.execute(""" + SELECT zekken_number, event_id, date + FROM rog_entry + WHERE team_id = %s + AND zekken_number IS NOT NULL + AND event_id IS NOT NULL + ORDER BY date DESC, id DESC + LIMIT 1 + """, (team_id,)) + + result = self.old_cursor.fetchone() + + if result: + zekken_number, event_id, entry_date = result + logger.debug(f"team_id {team_id}: zekken_number={zekken_number}, event_id={event_id}, date={entry_date}") + return str(zekken_number), event_id + else: + # rog_entryにレコードがない場合はデフォルト値を返す + logger.warning(f"team_id {team_id}: rog_entryにレコードが見つかりません") + return '', self.default_event_id + + except Exception as e: + logger.error(f"team_id {team_id} のzekken_number/event_id取得エラー: {e}") + return '', self.default_event_id + def get_default_event_id(self): """デフォルトのevent_idを取得または作成""" try: @@ -149,6 +178,9 @@ class RogTeamMigrator: """旧レコードを新レコード形式に変換""" old_id, old_team_name, old_category_id, old_owner_id = old_record + # team_idから最新のzekken_numberとevent_idを取得 + zekken_number, event_id = self.get_team_zekken_and_event(old_id) + # 新しいレコード作成 new_record = { 'id': old_id, @@ -157,11 +189,11 @@ class RogTeamMigrator: 'owner_id': old_owner_id, # 新しいフィールドにデフォルト値を設定 'class_name': '', # 空文字列 - 'event_id': self.default_event_id, # デフォルトイベント + 'event_id': event_id, # rog_entryから取得したevent_id 'location': None, # PostGIS座標は後で設定可能 'password': '', # パスワードなし 'trial': False, # 本番チーム - 'zekken_number': '', # ゼッケン番号なし + 'zekken_number': zekken_number, # rog_entryから取得したzekken_number 'created_at': datetime.now(timezone.utc), 'updated_at': datetime.now(timezone.utc) } @@ -202,6 +234,8 @@ class RogTeamMigrator: inserted_count = 0 updated_count = 0 error_count = 0 + zekken_resolved_count = 0 + constraint_avoided_count = 0 # レコード別処理 for i, old_record in enumerate(old_records): @@ -210,14 +244,33 @@ class RogTeamMigrator: new_record = self.convert_team_record(old_record, category_mapping) team_id = new_record['id'] - # 既存レコード確認 + # zekken_number解決統計 + if new_record['zekken_number']: + zekken_resolved_count += 1 + + # 既存レコード確認(IDベース) self.new_cursor.execute( "SELECT COUNT(*) FROM rog_team WHERE id = %s", (team_id,) ) - exists = self.new_cursor.fetchone()[0] > 0 + exists_by_id = self.new_cursor.fetchone()[0] > 0 - if exists: + # 重複制約確認(zekken_number + event_id の組み合わせ) + if new_record['zekken_number']: # zekken_numberが空でない場合のみチェック + self.new_cursor.execute( + "SELECT COUNT(*) FROM rog_team WHERE zekken_number = %s AND event_id = %s", + (new_record['zekken_number'], new_record['event_id']) + ) + exists_by_constraint = self.new_cursor.fetchone()[0] > 0 + + if exists_by_constraint and not exists_by_id: + # 制約違反が発生する場合は、zekken_numberを空にしてデフォルトevent_idを使用 + logger.warning(f"Team ID {team_id}: zekken_number制約回避のため空文字に変更") + new_record['zekken_number'] = '' + new_record['event_id'] = self.default_event_id + constraint_avoided_count += 1 + + if exists_by_id: # UPDATE処理 update_query = """ UPDATE rog_team SET @@ -306,6 +359,8 @@ class RogTeamMigrator: logger.info(f"挿入: {inserted_count}件") logger.info(f"更新: {updated_count}件") logger.info(f"エラー: {error_count}件") + logger.info(f"zekken_number解決: {zekken_resolved_count}件") + logger.info(f"制約回避: {constraint_avoided_count}件") logger.info(f"総処理: {len(old_records)}件") if error_count == 0: