181 lines
6.6 KiB
Python
181 lines
6.6 KiB
Python
|
|
#!/usr/bin/env python
|
|||
|
|
"""
|
|||
|
|
移行テスト用スクリプト
|
|||
|
|
現在のシステムの状況を詳細確認し、小規模テストを実行
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
import django
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
# Django settings setup
|
|||
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|||
|
|
sys.path.append(str(BASE_DIR))
|
|||
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
|||
|
|
django.setup()
|
|||
|
|
|
|||
|
|
from django.conf import settings
|
|||
|
|
from rog.models import GoalImages, CheckinImages
|
|||
|
|
from rog.services.s3_service import S3Service
|
|||
|
|
from django.core.files.base import ContentFile
|
|||
|
|
import json
|
|||
|
|
|
|||
|
|
def analyze_current_state():
|
|||
|
|
"""現在の状況を詳細分析"""
|
|||
|
|
print("🔍 現在のシステム状況分析")
|
|||
|
|
print("="*60)
|
|||
|
|
|
|||
|
|
# 設定確認
|
|||
|
|
print(f"MEDIA_ROOT: {settings.MEDIA_ROOT}")
|
|||
|
|
print(f"AWS S3 Bucket: {settings.AWS_STORAGE_BUCKET_NAME}")
|
|||
|
|
print(f"S3 Region: {settings.AWS_S3_REGION_NAME}")
|
|||
|
|
|
|||
|
|
# データベース状況
|
|||
|
|
goal_total = GoalImages.objects.count()
|
|||
|
|
goal_with_files = GoalImages.objects.filter(goalimage__isnull=False).exclude(goalimage='').count()
|
|||
|
|
checkin_total = CheckinImages.objects.count()
|
|||
|
|
checkin_with_files = CheckinImages.objects.filter(checkinimage__isnull=False).exclude(checkinimage='').count()
|
|||
|
|
|
|||
|
|
print(f"\nデータベース状況:")
|
|||
|
|
print(f" GoalImages: {goal_with_files}/{goal_total} (ファイル設定有り/総数)")
|
|||
|
|
print(f" CheckinImages: {checkin_with_files}/{checkin_total} (ファイル設定有り/総数)")
|
|||
|
|
|
|||
|
|
# ファイルパスの分析
|
|||
|
|
print(f"\n画像パスの分析:")
|
|||
|
|
|
|||
|
|
# GoalImages のパス例
|
|||
|
|
sample_goals = GoalImages.objects.filter(goalimage__isnull=False).exclude(goalimage='')[:5]
|
|||
|
|
print(f" GoalImages パス例:")
|
|||
|
|
for goal in sample_goals:
|
|||
|
|
full_path = os.path.join(settings.MEDIA_ROOT, str(goal.goalimage))
|
|||
|
|
exists = os.path.exists(full_path)
|
|||
|
|
print(f" Path: {goal.goalimage}")
|
|||
|
|
print(f" Full: {full_path}")
|
|||
|
|
print(f" Exists: {exists}")
|
|||
|
|
print(f" S3 URL?: {'s3' in str(goal.goalimage).lower() or 'amazonaws' in str(goal.goalimage).lower()}")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# CheckinImages のパス例
|
|||
|
|
sample_checkins = CheckinImages.objects.filter(checkinimage__isnull=False).exclude(checkinimage='')[:3]
|
|||
|
|
print(f" CheckinImages パス例:")
|
|||
|
|
for checkin in sample_checkins:
|
|||
|
|
full_path = os.path.join(settings.MEDIA_ROOT, str(checkin.checkinimage))
|
|||
|
|
exists = os.path.exists(full_path)
|
|||
|
|
print(f" Path: {checkin.checkinimage}")
|
|||
|
|
print(f" Full: {full_path}")
|
|||
|
|
print(f" Exists: {exists}")
|
|||
|
|
print(f" S3 URL?: {'s3' in str(checkin.checkinimage).lower() or 'amazonaws' in str(checkin.checkinimage).lower()}")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# パターン分析
|
|||
|
|
print(f"画像パスパターン分析:")
|
|||
|
|
|
|||
|
|
# 既存のS3 URLを確認
|
|||
|
|
s3_goals = GoalImages.objects.filter(goalimage__icontains='s3').count()
|
|||
|
|
s3_checkins = CheckinImages.objects.filter(checkinimage__icontains='s3').count()
|
|||
|
|
|
|||
|
|
amazonaws_goals = GoalImages.objects.filter(goalimage__icontains='amazonaws').count()
|
|||
|
|
amazonaws_checkins = CheckinImages.objects.filter(checkinimage__icontains='amazonaws').count()
|
|||
|
|
|
|||
|
|
print(f" S3を含むパス - Goal: {s3_goals}, Checkin: {s3_checkins}")
|
|||
|
|
print(f" AmazonAWSを含むパス - Goal: {amazonaws_goals}, Checkin: {amazonaws_checkins}")
|
|||
|
|
|
|||
|
|
# ローカルファイルパターン
|
|||
|
|
local_goals = goal_with_files - s3_goals - amazonaws_goals
|
|||
|
|
local_checkins = checkin_with_files - s3_checkins - amazonaws_checkins
|
|||
|
|
|
|||
|
|
print(f" ローカルパスと思われる - Goal: {local_goals}, Checkin: {local_checkins}")
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
'goal_total': goal_total,
|
|||
|
|
'goal_with_files': goal_with_files,
|
|||
|
|
'checkin_total': checkin_total,
|
|||
|
|
'checkin_with_files': checkin_with_files,
|
|||
|
|
'local_goals': local_goals,
|
|||
|
|
'local_checkins': local_checkins,
|
|||
|
|
's3_goals': s3_goals + amazonaws_goals,
|
|||
|
|
's3_checkins': s3_checkins + amazonaws_checkins
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def test_s3_connection():
|
|||
|
|
"""S3接続テスト"""
|
|||
|
|
print("\n🔗 S3接続テスト")
|
|||
|
|
print("="*60)
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
s3_service = S3Service()
|
|||
|
|
|
|||
|
|
# テストファイルをアップロード
|
|||
|
|
test_content = b"MIGRATION TEST - CONNECTION VERIFICATION"
|
|||
|
|
test_file = ContentFile(test_content, name="migration_test.jpg")
|
|||
|
|
|
|||
|
|
s3_url = s3_service.upload_checkin_image(
|
|||
|
|
image_file=test_file,
|
|||
|
|
event_code="migration-test",
|
|||
|
|
team_code="TEST-TEAM",
|
|||
|
|
cp_number=999
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print(f"✅ S3接続成功: {s3_url}")
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"❌ S3接続失敗: {str(e)}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def create_test_migration_plan(stats):
|
|||
|
|
"""テスト移行計画を作成"""
|
|||
|
|
print("\n📋 移行計画の提案")
|
|||
|
|
print("="*60)
|
|||
|
|
|
|||
|
|
total_to_migrate = stats['local_goals'] + stats['local_checkins']
|
|||
|
|
|
|||
|
|
if total_to_migrate == 0:
|
|||
|
|
print("✅ 移行が必要なローカル画像はありません。")
|
|||
|
|
print(" すべての画像が既にS3に移行済みか、外部ストレージに保存されています。")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f"移行対象画像数: {total_to_migrate:,}件")
|
|||
|
|
print(f" - ゴール画像: {stats['local_goals']:,}件")
|
|||
|
|
print(f" - チェックイン画像: {stats['local_checkins']:,}件")
|
|||
|
|
print()
|
|||
|
|
print("推奨移行手順:")
|
|||
|
|
print("1. 小規模テスト移行(10件程度)")
|
|||
|
|
print("2. 中規模テスト移行(100件程度)")
|
|||
|
|
print("3. バッチ処理での完全移行")
|
|||
|
|
print()
|
|||
|
|
print("予想処理時間:")
|
|||
|
|
print(f" - 小規模テスト: 約1分")
|
|||
|
|
print(f" - 中規模テスト: 約10分")
|
|||
|
|
print(f" - 完全移行: 約{total_to_migrate // 100}時間")
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
"""メイン実行"""
|
|||
|
|
print("🚀 S3移行準備状況チェック")
|
|||
|
|
print("="*60)
|
|||
|
|
|
|||
|
|
# 1. 現状分析
|
|||
|
|
stats = analyze_current_state()
|
|||
|
|
|
|||
|
|
# 2. S3接続テスト
|
|||
|
|
s3_ok = test_s3_connection()
|
|||
|
|
|
|||
|
|
# 3. 移行計画
|
|||
|
|
if s3_ok:
|
|||
|
|
needs_migration = create_test_migration_plan(stats)
|
|||
|
|
|
|||
|
|
if not needs_migration:
|
|||
|
|
print("\n🎉 移行作業は不要です。")
|
|||
|
|
else:
|
|||
|
|
print("\n次のステップ:")
|
|||
|
|
print("1. python run_small_migration_test.py # 小規模テスト")
|
|||
|
|
print("2. python run_full_migration.py # 完全移行")
|
|||
|
|
else:
|
|||
|
|
print("\n⚠️ S3接続に問題があります。AWS設定を確認してください。")
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|