146 lines
4.9 KiB
Python
146 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simplified Ground Zero Database Purge Script
|
|
|
|
Deletes ALL test users and lets database cascade constraints handle the rest.
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
from sqlalchemy import text
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
# Import settings
|
|
sys.path.insert(0, '/app')
|
|
from app.core.config import settings
|
|
|
|
async def purge_test_data_simple():
|
|
"""Simple purge function using cascade delete"""
|
|
# Create async engine
|
|
engine = create_async_engine(
|
|
str(settings.SQLALCHEMY_DATABASE_URI),
|
|
echo=False,
|
|
pool_size=5,
|
|
max_overflow=10,
|
|
)
|
|
|
|
async_session = sessionmaker(
|
|
engine, class_=AsyncSession, expire_on_commit=False
|
|
)
|
|
|
|
async with async_session() as session:
|
|
try:
|
|
print("🔍 Starting Ground Zero database purge (simplified)...")
|
|
print("=" * 60)
|
|
|
|
# 1. First, identify test users to delete
|
|
test_email_patterns = [
|
|
'%test%',
|
|
'%noreply%',
|
|
'%profibot%',
|
|
'tester_pro@profibot.hu',
|
|
'test@example.com',
|
|
'%example.com',
|
|
'%@gmail.com' # Also delete gmail test users
|
|
]
|
|
|
|
# Build WHERE clause for test users
|
|
where_conditions = []
|
|
for pattern in test_email_patterns:
|
|
where_conditions.append(f"email ILIKE '{pattern}'")
|
|
|
|
where_clause = " OR ".join(where_conditions)
|
|
|
|
# 2. Get count of test users
|
|
count_query = text(f"""
|
|
SELECT COUNT(*)
|
|
FROM identity.users
|
|
WHERE {where_clause}
|
|
AND is_deleted = false
|
|
""")
|
|
|
|
result = await session.execute(count_query)
|
|
test_user_count = result.scalar()
|
|
|
|
if test_user_count == 0:
|
|
print("✅ No test users found to delete.")
|
|
return
|
|
|
|
# 3. Get list of test users
|
|
list_query = text(f"""
|
|
SELECT id, email
|
|
FROM identity.users
|
|
WHERE {where_clause}
|
|
AND is_deleted = false
|
|
LIMIT 20
|
|
""")
|
|
|
|
result = await session.execute(list_query)
|
|
test_users = result.fetchall()
|
|
|
|
print(f"📋 Found {test_user_count} test users to delete:")
|
|
for user in test_users:
|
|
print(f" - {user[1]} (ID: {user[0]})")
|
|
if test_user_count > 20:
|
|
print(f" ... and {test_user_count - 20} more")
|
|
|
|
# 4. Delete users (cascade will handle related records)
|
|
delete_query = text(f"""
|
|
DELETE FROM identity.users
|
|
WHERE {where_clause}
|
|
AND is_deleted = false
|
|
RETURNING id, email
|
|
""")
|
|
|
|
print("\n🗑️ Deleting test users (cascade delete will handle related records)...")
|
|
result = await session.execute(delete_query)
|
|
deleted_users = result.fetchall()
|
|
|
|
# 5. Also delete any orphaned persons
|
|
cleanup_persons_query = text("""
|
|
DELETE FROM identity.persons
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM identity.users
|
|
WHERE users.person_id = persons.id
|
|
)
|
|
RETURNING id
|
|
""")
|
|
|
|
result = await session.execute(cleanup_persons_query)
|
|
orphaned_persons = result.rowcount
|
|
|
|
# Commit transaction
|
|
await session.commit()
|
|
|
|
print("=" * 60)
|
|
print("✅ Ground Zero purge completed successfully!")
|
|
print(f"\n📊 Deletion Summary:")
|
|
print(f" Test users deleted: {len(deleted_users)}")
|
|
print(f" Orphaned persons cleaned up: {orphaned_persons}")
|
|
|
|
# 6. Verify cleanup
|
|
verify_query = text(f"""
|
|
SELECT COUNT(*)
|
|
FROM identity.users
|
|
WHERE {where_clause}
|
|
AND is_deleted = false
|
|
""")
|
|
|
|
result = await session.execute(verify_query)
|
|
remaining = result.scalar()
|
|
|
|
if remaining == 0:
|
|
print(f"\n✅ Verification: All test users have been removed.")
|
|
else:
|
|
print(f"\n⚠️ Verification: {remaining} test users still remain.")
|
|
|
|
return len(deleted_users)
|
|
|
|
except Exception as e:
|
|
await session.rollback()
|
|
print(f"❌ Error during purge: {e}")
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(purge_test_data_simple()) |