Update authentication system, database models, and UI components
This commit is contained in:
174
fix_db_constraints.py
Normal file
174
fix_db_constraints.py
Normal file
@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Fix Database Constraints and Legacy Data
|
||||
Handles foreign key constraints properly during cleanup
|
||||
"""
|
||||
|
||||
import sys
|
||||
from sqlmodel import Session, text
|
||||
from database import engine
|
||||
|
||||
def execute_query(session, query, description):
|
||||
"""Execute a query and report results"""
|
||||
print(f"\n{description}")
|
||||
print(f"Query: {query}")
|
||||
|
||||
try:
|
||||
result = session.exec(text(query))
|
||||
if query.strip().upper().startswith('SELECT'):
|
||||
rows = result.fetchall()
|
||||
print(f"Result: {len(rows)} rows")
|
||||
for row in rows:
|
||||
print(f" {row}")
|
||||
else:
|
||||
session.commit()
|
||||
print(f"✅ Success: {result.rowcount} rows affected")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
session.rollback()
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""Fix database constraints and legacy data"""
|
||||
print("=== FIXING DATABASE CONSTRAINTS AND LEGACY DATA ===")
|
||||
|
||||
with Session(engine) as session:
|
||||
|
||||
# Step 1: First, let's temporarily drop the foreign key constraint
|
||||
print("\n=== STEP 1: Handle Foreign Key Constraint ===")
|
||||
|
||||
# Check current constraint
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT conname, conrelid::regclass, confrelid::regclass
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'dbsession_user_id_fkey'""",
|
||||
"Check existing foreign key constraint"
|
||||
)
|
||||
|
||||
# Drop the constraint temporarily
|
||||
execute_query(
|
||||
session,
|
||||
"""ALTER TABLE dbsession DROP CONSTRAINT IF EXISTS dbsession_user_id_fkey""",
|
||||
"Drop foreign key constraint temporarily"
|
||||
)
|
||||
|
||||
# Step 2: Update user table
|
||||
print("\n=== STEP 2: Update User Table ===")
|
||||
execute_query(
|
||||
session,
|
||||
"""UPDATE "user"
|
||||
SET username = email,
|
||||
display_name = CASE
|
||||
WHEN display_name = '' OR display_name IS NULL
|
||||
THEN split_part(email, '@', 1)
|
||||
ELSE display_name
|
||||
END
|
||||
WHERE email = 'oib@chello.at'""",
|
||||
"Update user username to match email"
|
||||
)
|
||||
|
||||
# Verify user update
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT email, username, display_name FROM "user" WHERE email = 'oib@chello.at'""",
|
||||
"Verify user table update"
|
||||
)
|
||||
|
||||
# Step 3: Update session user_id references
|
||||
print("\n=== STEP 3: Update Session References ===")
|
||||
execute_query(
|
||||
session,
|
||||
"""UPDATE dbsession
|
||||
SET user_id = 'oib@chello.at'
|
||||
WHERE user_id = 'oibchello'""",
|
||||
"Update session user_id to email format"
|
||||
)
|
||||
|
||||
# Verify session updates
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT DISTINCT user_id FROM dbsession""",
|
||||
"Verify session user_id updates"
|
||||
)
|
||||
|
||||
# Step 4: Recreate the foreign key constraint
|
||||
print("\n=== STEP 4: Recreate Foreign Key Constraint ===")
|
||||
execute_query(
|
||||
session,
|
||||
"""ALTER TABLE dbsession
|
||||
ADD CONSTRAINT dbsession_user_id_fkey
|
||||
FOREIGN KEY (user_id) REFERENCES "user"(username)""",
|
||||
"Recreate foreign key constraint"
|
||||
)
|
||||
|
||||
# Step 5: Final verification - check for remaining issues
|
||||
print("\n=== STEP 5: Final Verification ===")
|
||||
|
||||
# Check user email/username match
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT email, username,
|
||||
CASE WHEN email = username THEN '✓ Match' ELSE '✗ Mismatch' END as status
|
||||
FROM "user""",
|
||||
"Check user email/username consistency"
|
||||
)
|
||||
|
||||
# Check expired sessions
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT COUNT(*) as expired_active_sessions
|
||||
FROM dbsession
|
||||
WHERE expires_at < NOW() AND is_active = true""",
|
||||
"Check for expired active sessions"
|
||||
)
|
||||
|
||||
# Check PublicStream consistency
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT uid, username,
|
||||
CASE WHEN uid = username THEN '✓ Match' ELSE '✗ Mismatch' END as status
|
||||
FROM publicstream""",
|
||||
"Check PublicStream UID/username consistency"
|
||||
)
|
||||
|
||||
# Check for orphaned records
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT 'userquota' as table_name, COUNT(*) as orphaned_records
|
||||
FROM userquota q
|
||||
LEFT JOIN "user" u ON q.uid = u.email
|
||||
WHERE u.email IS NULL
|
||||
UNION ALL
|
||||
SELECT 'publicstream' as table_name, COUNT(*) as orphaned_records
|
||||
FROM publicstream p
|
||||
LEFT JOIN "user" u ON p.uid = u.email
|
||||
WHERE u.email IS NULL""",
|
||||
"Check for orphaned records"
|
||||
)
|
||||
|
||||
# Summary of current state
|
||||
print("\n=== DATABASE STATE SUMMARY ===")
|
||||
execute_query(
|
||||
session,
|
||||
"""SELECT
|
||||
COUNT(DISTINCT u.email) as total_users,
|
||||
COUNT(DISTINCT q.uid) as quota_records,
|
||||
COUNT(DISTINCT p.uid) as stream_records,
|
||||
COUNT(CASE WHEN s.is_active THEN 1 END) as active_sessions,
|
||||
COUNT(CASE WHEN s.expires_at < NOW() AND s.is_active THEN 1 END) as expired_active_sessions
|
||||
FROM "user" u
|
||||
FULL OUTER JOIN userquota q ON u.email = q.uid
|
||||
FULL OUTER JOIN publicstream p ON u.email = p.uid
|
||||
FULL OUTER JOIN dbsession s ON u.username = s.user_id""",
|
||||
"Database state summary"
|
||||
)
|
||||
|
||||
print("\n✅ Database cleanup completed!")
|
||||
print("All legacy data issues should now be resolved.")
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Reference in New Issue
Block a user