File size: 3,917 Bytes
8c49d21 6bd3a21 8c49d21 8a9ebcc 766ef88 493a4a6 6ec5390 493a4a6 8a9ebcc 8c49d21 8a9ebcc 493a4a6 8a9ebcc 493a4a6 6ec5390 493a4a6 6ec5390 8a9ebcc 493a4a6 766ef88 493a4a6 766ef88 493a4a6 766ef88 493a4a6 766ef88 493a4a6 766ef88 493a4a6 766ef88 6bd3a21 766ef88 6bd3a21 766ef88 493a4a6 766ef88 493a4a6 766ef88 493a4a6 766ef88 493a4a6 8a9ebcc c8ee503 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | # SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
# SPDX-License-Identifier: Apache-2.0
import os
import logging
import asyncio
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete
from api.database import async_engine, Base, User, OAuthAccount, Conversation, Message, AsyncSessionLocal
from passlib.context import CryptContext
# إعداد اللوج
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# إعداد تشفير كلمة المرور
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
async def init_db():
logger.info("Starting database initialization...")
# إنشاء الجداول
try:
async with async_engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
logger.info("Database tables created successfully.")
except Exception as e:
logger.error(f"Error creating database tables: {e}")
raise
# تنظيف البيانات غير المتسقة
async with AsyncSessionLocal() as session:
try:
# حذف سجلات oauth_accounts اللي مش مرتبطة بمستخدم موجود
stmt = delete(OAuthAccount).where(
OAuthAccount.user_id.notin_(select(User.id))
)
result = await session.execute(stmt)
deleted_count = result.rowcount
await session.commit()
logger.info(f"Deleted {deleted_count} orphaned OAuth accounts.")
# التأكد من إن كل المستخدمين ليهم is_active=True
users = (await session.execute(select(User))).scalars().all()
for user in users:
if not user.is_active:
user.is_active = True
logger.info(f"Updated user {user.email} to is_active=True")
await session.commit()
# اختبار إنشاء مستخدم ومحادثة (اختياري)
test_user = (await session.execute(
select(User).filter_by(email="test@example.com")
)).scalar_one_or_none()
if not test_user:
# استخدام كلمة مرور أقصر لتجنب مشكلة bcrypt
test_password = "testpass"
if len(test_password.encode('utf-8')) > 72:
logger.error("Test password is too long for bcrypt (>72 bytes)")
raise ValueError("Test password is too long for bcrypt (>72 bytes)")
test_user = User(
email="test@example.com",
hashed_password=pwd_context.hash(test_password),
is_active=True,
display_name="Test User"
)
session.add(test_user)
await session.commit()
logger.info("Test user created successfully.")
test_conversation = (await session.execute(
select(Conversation).filter_by(user_id=test_user.id)
)).scalar_one_or_none()
if not test_conversation:
test_conversation = Conversation(
conversation_id="test-conversation-1",
user_id=test_user.id,
title="Test Conversation"
)
session.add(test_conversation)
await session.commit()
logger.info("Test conversation created successfully.")
except Exception as e:
await session.rollback()
logger.error(f"Error during initialization: {e}")
raise
finally:
await session.close()
logger.info("Database initialization completed.")
if __name__ == "__main__":
try:
asyncio.run(init_db())
except Exception as e:
logger.error(f"Failed to initialize database: {e}")
raise
|