#!/usr/bin/env python3 """ Location2025簡単移行プログラム 高山2イベント以外のデータも含めた完全移行 """ import os import sys from datetime import datetime # Django設定の初期化 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') sys.path.append('/app') try: import django django.setup() from django.contrib.gis.geos import Point from django.db import models from rog.models import Location, Location2025, NewEvent2 except ImportError as e: print(f"Django import error: {e}") print("このスクリプトはDjangoコンテナ内で実行してください") sys.exit(1) def simple_location2025_migration(): """簡単なLocation2025移行(残りデータを高山2イベントとして移行)""" print("=== Location2025簡単移行開始 ===") try: # 現在の状況確認 total_location = Location.objects.count() current_location2025 = Location2025.objects.count() remaining = total_location - current_location2025 print(f"移行対象: {remaining}件 (全{total_location}件中{current_location2025}件移行済み)") if remaining <= 0: print("✅ すべてのLocationデータが既にLocation2025に移行済みです") return True # 高山2イベントを取得 takayama_event = NewEvent2.objects.filter(event_code='高山2').first() if not takayama_event: print("❌ 高山2イベントが見つかりません") return False print(f"✅ 高山2イベント (ID: {takayama_event.id}) を使用") # 既存のLocation2025データと重複チェック(IDベース) existing_location2025_ids = set( Location2025.objects.values_list('id', flat=True) ) # 未移行のLocationデータを取得(全体から処理) pending_locations = Location.objects.all() pending_count = pending_locations.count() print(f"総データ: {pending_count}件を処理中...") # バッチ処理でLocation2025に移行 batch_size = 100 total_migrated = 0 for i in range(0, pending_count, batch_size): batch_locations = list(pending_locations[i:i+batch_size]) location2025_objects = [] for location in batch_locations: try: # PostGIS Pointオブジェクト作成 point_geom = Point(float(location.longitude), float(location.latitude)) location2025_obj = Location2025( cp_number=location.location_id, # location_idを使用 event=takayama_event, cp_name=f"CP{location.location_id}", latitude=location.latitude, longitude=location.longitude, location=point_geom, cp_point=int(location.cp) if location.cp is not None else 10, photo_point=0, buy_point=0, checkin_radius=50.0, auto_checkin=False, shop_closed=False, shop_shutdown=False, opening_hours="", address=location.address or "", phone=location.phone or "", website="", description=f"移行データ (Location ID: {location.id})", is_active=True, sort_order=location.location_id, csv_source_file="migration_from_location", csv_upload_date=datetime.now(), created_at=location.created_at or datetime.now(), updated_at=datetime.now() ) location2025_objects.append(location2025_obj) except Exception as e: print(f"⚠️ Location ID {location.id} 変換エラー: {e}") continue # 一括挿入 if location2025_objects: try: Location2025.objects.bulk_create(location2025_objects, ignore_conflicts=True) total_migrated += len(location2025_objects) print(f"移行進捗: {total_migrated}/{pending_count}件完了") except Exception as e: print(f"⚠️ バッチ{i//batch_size + 1} 挿入エラー: {e}") continue # 移行結果確認 final_location2025_count = Location2025.objects.count() print(f"\n✅ 移行完了: Location2025テーブルに{final_location2025_count}件のデータ") print(f"今回移行: {total_migrated}件") return True except Exception as e: print(f"❌ 移行エラー: {e}") return False def verify_migration_results(): """移行結果の検証""" print("\n=== 移行結果検証 ===") try: # データ数確認 location_count = Location.objects.count() location2025_count = Location2025.objects.count() print(f"Location (旧): {location_count}件") print(f"Location2025 (新): {location2025_count}件") if location2025_count >= location_count: print("✅ 完全移行成功") else: remaining = location_count - location2025_count print(f"⚠️ {remaining}件が未移行") # サンプルデータ確認 sample_data = Location2025.objects.all()[:5] print("\nLocation2025サンプルデータ:") for item in sample_data: print(f" CP{item.cp_number}: ({item.longitude:.6f}, {item.latitude:.6f}) - {item.cp_point}点") return True except Exception as e: print(f"❌ 検証エラー: {e}") return False def main(): """メイン処理""" print("=== Location2025簡単移行プログラム ===") print("方針: 残りのLocationデータを高山2イベントとして一括移行") # 移行実行 success = simple_location2025_migration() if success: # 結果検証 verify_migration_results() print("\n🎉 Location2025移行プログラム完了") else: print("\n❌ 移行に失敗しました") return 1 return 0 if __name__ == "__main__": exit(main())