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

333 lines
12 KiB
Python
Raw Permalink 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 への全イベントデータ移行スクリプトSQL生成方式
FC岐阜の成功事例をベースに全てのイベントのteam/member/entry + GPS情報を移行
"""
import os
import sys
import django
from datetime import datetime
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
django.setup()
from django.db import transaction, connection
from rog.models import NewEvent2, Team, Entry, Member, NewCategory, CustomUser
print("📋 全イベントデータ移行スクリプトSQL生成方式を開始します")
# SQLファイル名
sql_file = "migrate_all_events_with_gps.sql"
try:
with transaction.atomic():
# === STEP 1: ユーザー確認 ===
print("\n=== STEP 1: ユーザー確認 ===")
admin_user, created = CustomUser.objects.get_or_create(
username='admin',
defaults={
'email': 'admin@example.com',
'is_staff': True,
'is_superuser': True
}
)
print(f"管理ユーザー: {'作成' if created else '既存'}")
# === STEP 2: イベントとカテゴリー情報取得 ===
print("\n=== STEP 2: 既存イベント・カテゴリー確認 ===")
existing_events = list(NewEvent2.objects.values_list('id', 'name'))
print(f"既存イベント数: {len(existing_events)}")
if not existing_events:
print("❌ イベントが存在しません。先にイベントを作成してください。")
sys.exit(1)
existing_categories = list(NewCategory.objects.values_list('id', 'name'))
print(f"既存カテゴリー数: {len(existing_categories)}")
if not existing_categories:
print("❌ カテゴリーが存在しません。先にカテゴリーを作成してください。")
sys.exit(1)
# === STEP 3: SQLファイル生成 ===
print(f"\n=== STEP 3: SQLファイル生成 ({sql_file}) ===")
with open(sql_file, 'w', encoding='utf-8') as f:
f.write("-- 全イベントデータ移行SQLGPS情報含む\n")
f.write(f"-- 生成日時: {datetime.now()}\n\n")
# 1. チーム移行SQL
f.write("-- ========================================\n")
f.write("-- 1. チーム移行old_rogdb → rogdb\n")
f.write("-- ========================================\n\n")
f.write("""
-- old_rogdbからチーム情報を移行
INSERT INTO rog_team (
id, name, owner_id, event_id, reg_date,
representative_name, representative_phone,
representative_email, is_deleted
)
SELECT DISTINCT
t.id,
t.name,
COALESCE(t.owner_id, {admin_user_id}) as owner_id,
t.event_id,
t.reg_date,
COALESCE(t.representative_name, t.name) as representative_name,
COALESCE(t.representative_phone, '') as representative_phone,
COALESCE(t.representative_email, '') as representative_email,
false as is_deleted
FROM dblink('host=postgres-db port=5432 dbname=old_rogdb user=user password=password',
'SELECT id, name, owner_id, event_id, reg_date, representative_name, representative_phone, representative_email FROM team WHERE is_deleted = false'
) AS t(
id INTEGER,
name TEXT,
owner_id INTEGER,
event_id INTEGER,
reg_date TIMESTAMP,
representative_name TEXT,
representative_phone TEXT,
representative_email TEXT
)
WHERE EXISTS (
SELECT 1 FROM rog_newevent2 ne WHERE ne.id = t.event_id
)
AND NOT EXISTS (
SELECT 1 FROM rog_team rt WHERE rt.id = t.id
)
ORDER BY t.id;
""".format(admin_user_id=admin_user.id))
# 2. メンバー移行SQL
f.write("-- ========================================\n")
f.write("-- 2. メンバー移行old_rogdb → rogdb\n")
f.write("-- ========================================\n\n")
f.write("""
-- old_rogdbからメンバー情報を移行
INSERT INTO rog_member (
id, team_id, name, kana, is_leader,
phone, email, birthday, gender, si_number, is_deleted
)
SELECT DISTINCT
m.id,
m.team_id,
m.name,
COALESCE(m.kana, '') as kana,
COALESCE(m.is_leader, false) as is_leader,
COALESCE(m.phone, '') as phone,
COALESCE(m.email, '') as email,
m.birthday,
COALESCE(m.gender, '') as gender,
m.si_number,
false as is_deleted
FROM dblink('host=postgres-db port=5432 dbname=old_rogdb user=user password=password',
'SELECT id, team_id, name, kana, is_leader, phone, email, birthday, gender, si_number FROM member WHERE is_deleted = false'
) AS m(
id INTEGER,
team_id INTEGER,
name TEXT,
kana TEXT,
is_leader BOOLEAN,
phone TEXT,
email TEXT,
birthday DATE,
gender TEXT,
si_number TEXT
)
WHERE EXISTS (
SELECT 1 FROM rog_team rt WHERE rt.id = m.team_id
)
AND NOT EXISTS (
SELECT 1 FROM rog_member rm WHERE rm.id = m.id
)
ORDER BY m.id;
""")
# 3. エントリー移行SQL
f.write("-- ========================================\n")
f.write("-- 3. エントリー移行old_rogdb → rogdb\n")
f.write("-- ========================================\n\n")
default_cat_id = existing_categories[0][0] if existing_categories else 1
f.write(f"""
-- old_rogdbからエントリー情報を移行startテーブルと結合
INSERT INTO rog_entry (
date, category_id, event_id, owner_id, team_id,
is_active, zekken_number, zekken_label, has_goaled,
has_participated, is_trial, staff_privileges,
can_access_private_events, team_validation_status
)
SELECT DISTINCT
ne.start_datetime as date,
{default_cat_id} as category_id,
t.event_id,
COALESCE(t.owner_id, {admin_user.id}) as owner_id,
t.team_id,
true as is_active,
COALESCE(s.zekken_number, 0) as zekken_number,
COALESCE(s.label, CONCAT(ne.name, '-', COALESCE(s.zekken_number, 0))) as zekken_label,
false as has_goaled,
false as has_participated,
false as is_trial,
false as staff_privileges,
false as can_access_private_events,
'approved' as team_validation_status
FROM dblink('host=postgres-db port=5432 dbname=old_rogdb user=user password=password',
'SELECT t.id as team_id, t.event_id, t.owner_id, s.zekken_number, s.label
FROM team t
LEFT JOIN start s ON t.id = s.team_id
WHERE t.is_deleted = false'
) AS t(
team_id INTEGER,
event_id INTEGER,
owner_id INTEGER,
zekken_number INTEGER,
label TEXT
)
JOIN rog_newevent2 ne ON ne.id = t.event_id
WHERE EXISTS (
SELECT 1 FROM rog_team rt WHERE rt.id = t.team_id
)
AND NOT EXISTS (
SELECT 1 FROM rog_entry re WHERE re.team_id = t.team_id AND re.event_id = t.event_id
)
ORDER BY t.team_id;
""")
# 4. GPS情報移行SQL
f.write("-- ========================================\n")
f.write("-- 4. GPS情報移行gifuroge → rogdb\n")
f.write("-- ========================================\n\n")
f.write("""
-- gifurogeからGPS情報を移行gps_information → gps_checkins
INSERT INTO gps_checkins (
path_order, zekken_number, event_code, cp_number,
lattitude, longitude, image_address, image_receipt,
image_qr, validate_location, goal_time, late_point,
create_at, create_user, update_at, update_user,
buy_flag, colabo_company_memo, points, event_id,
team_id, validation_status
)
SELECT DISTINCT
0 as path_order,
gps.zekken_number,
gps.event_code,
gps.cp_number,
gps.lattitude,
gps.longitude,
COALESCE(gps.image_address, '') as image_address,
COALESCE(gps.image_receipt, '') as image_receipt,
COALESCE(gps.image_qr, false) as image_qr,
COALESCE(gps.validate_location, false) as validate_location,
COALESCE(gps.goal_time, '') as goal_time,
COALESCE(gps.late_point, 0) as late_point,
COALESCE(gps.create_at, NOW()) as create_at,
COALESCE(gps.create_user, '') as create_user,
COALESCE(gps.update_at, NOW()) as update_at,
COALESCE(gps.update_user, '') as update_user,
COALESCE(gps.buy_flag, false) as buy_flag,
COALESCE(gps.colabo_company_memo, '') as colabo_company_memo,
COALESCE(gps.points, 0) as points,
ent.event_id,
ent.team_id,
'pending' as validation_status
FROM dblink('host=postgres-db port=5432 dbname=gifuroge user=user password=password',
'SELECT zekken_number, event_code, cp_number, lattitude, longitude,
image_address, image_receipt, image_qr, validate_location,
goal_time, late_point, create_at, create_user, update_at,
update_user, buy_flag, colabo_company_memo, points
FROM gps_information
ORDER BY create_at'
) AS gps(
zekken_number TEXT,
event_code TEXT,
cp_number INTEGER,
lattitude DOUBLE PRECISION,
longitude DOUBLE PRECISION,
image_address TEXT,
image_receipt TEXT,
image_qr BOOLEAN,
validate_location BOOLEAN,
goal_time TEXT,
late_point INTEGER,
create_at TIMESTAMP,
create_user TEXT,
update_at TIMESTAMP,
update_user TEXT,
buy_flag BOOLEAN,
colabo_company_memo TEXT,
points INTEGER
)
LEFT JOIN rog_entry ent ON ent.zekken_number = CAST(gps.zekken_number AS INTEGER)
WHERE ent.id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM gps_checkins gc
WHERE gc.zekken_number = gps.zekken_number
AND gc.event_code = gps.event_code
AND gc.cp_number = gps.cp_number
AND gc.create_at = gps.create_at
);
""")
# 5. 統計クエリ
f.write("-- ========================================\n")
f.write("-- 5. 移行結果確認クエリ\n")
f.write("-- ========================================\n\n")
f.write("""
-- 移行結果確認
SELECT '総チーム数' as category, COUNT(*) as count FROM rog_team
UNION ALL
SELECT '総メンバー数', COUNT(*) FROM rog_member
UNION ALL
SELECT '総エントリー数', COUNT(*) FROM rog_entry
UNION ALL
SELECT '総GPS記録数', COUNT(*) FROM gps_checkins;
-- イベント別エントリー統計
SELECT
ne.name as event_name,
COUNT(re.id) as entry_count,
COUNT(gc.id) as gps_count
FROM rog_newevent2 ne
LEFT JOIN rog_entry re ON ne.id = re.event_id
LEFT JOIN gps_checkins gc ON ne.id = gc.event_id
GROUP BY ne.id, ne.name
ORDER BY entry_count DESC;
""")
print(f"✅ SQLファイル生成完了: {sql_file}")
# === STEP 4: 実行方法の案内 ===
print("\n=== STEP 4: 実行方法 ===")
print(f"📝 生成されたSQLファイル: {sql_file}")
print("\n🚀 実行方法:")
print("1. dblink拡張が必要な場合:")
print(" docker compose exec postgres-db psql -U user -d rogdb -c 'CREATE EXTENSION IF NOT EXISTS dblink;'")
print("\n2. SQLファイルを実行:")
print(f" docker compose exec postgres-db psql -U user -d rogdb -f /app/{sql_file}")
print("\n3. 結果確認:")
print(" docker compose exec postgres-db psql -U user -d rogdb -c 'SELECT COUNT(*) FROM rog_entry;'")
print(" docker compose exec postgres-db psql -U user -d rogdb -c 'SELECT COUNT(*) FROM gps_checkins;'")
print("\n✅ SQL移行スクリプト生成が完了しました")
print("🎯 上記のコマンドを実行して、全イベントデータGPS情報を移行してください。")
except Exception as e:
print(f"❌ エラーが発生しました: {e}")
import traceback
traceback.print_exc()