Mark-Lasfar
commited on
Commit
·
766ef88
1
Parent(s):
84f413e
Update Model
Browse files- api/database.py +17 -25
- init_db.py +50 -18
api/database.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
| 1 |
import os
|
| 2 |
-
from sqlalchemy import Column, String, Integer, ForeignKey, DateTime, Boolean
|
| 3 |
-
from sqlalchemy import create_engine
|
| 4 |
from sqlalchemy.ext.declarative import declarative_base
|
| 5 |
from sqlalchemy.orm import sessionmaker, relationship
|
| 6 |
-
from sqlalchemy
|
| 7 |
from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase
|
| 8 |
from sqlalchemy.orm import Session
|
| 9 |
from typing import AsyncGenerator
|
|
@@ -13,7 +12,7 @@ from datetime import datetime
|
|
| 13 |
# جلب URL قاعدة البيانات من المتغيرات البيئية
|
| 14 |
SQLALCHEMY_DATABASE_URL = os.getenv("SQLALCHEMY_DATABASE_URL")
|
| 15 |
if not SQLALCHEMY_DATABASE_URL:
|
| 16 |
-
raise ValueError("SQLALCHEMY_DATABASE_URL is not set in environment variables.")
|
| 17 |
|
| 18 |
# إنشاء المحرك
|
| 19 |
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
|
@@ -26,7 +25,6 @@ Base = declarative_base()
|
|
| 26 |
|
| 27 |
class OAuthAccount(Base):
|
| 28 |
__tablename__ = "oauth_account"
|
| 29 |
-
|
| 30 |
id = Column(Integer, primary_key=True, index=True)
|
| 31 |
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
| 32 |
oauth_name = Column(String, nullable=False)
|
|
@@ -35,12 +33,10 @@ class OAuthAccount(Base):
|
|
| 35 |
refresh_token = Column(String, nullable=True)
|
| 36 |
account_id = Column(String, index=True, nullable=False)
|
| 37 |
account_email = Column(String, nullable=False)
|
| 38 |
-
|
| 39 |
user = relationship("User", back_populates="oauth_accounts")
|
| 40 |
|
| 41 |
class User(SQLAlchemyBaseUserTable[int], Base):
|
| 42 |
__tablename__ = "user"
|
| 43 |
-
|
| 44 |
id = Column(Integer, primary_key=True, index=True)
|
| 45 |
email = Column(String, unique=True, index=True, nullable=False)
|
| 46 |
hashed_password = Column(String, nullable=False)
|
|
@@ -52,32 +48,29 @@ class User(SQLAlchemyBaseUserTable[int], Base):
|
|
| 52 |
job_title = Column(String, nullable=True)
|
| 53 |
education = Column(String, nullable=True)
|
| 54 |
interests = Column(String, nullable=True)
|
| 55 |
-
additional_info = Column(
|
| 56 |
conversation_style = Column(String, nullable=True)
|
| 57 |
oauth_accounts = relationship("OAuthAccount", back_populates="user", cascade="all, delete-orphan")
|
|
|
|
| 58 |
|
| 59 |
class Conversation(Base):
|
| 60 |
__tablename__ = "conversation"
|
| 61 |
-
|
| 62 |
id = Column(Integer, primary_key=True, index=True)
|
| 63 |
-
conversation_id = Column(String, unique=True, index=True)
|
| 64 |
-
user_id = Column(Integer, ForeignKey("user.id"))
|
| 65 |
-
title = Column(String)
|
| 66 |
-
created_at = Column(DateTime
|
| 67 |
-
updated_at = Column(DateTime
|
| 68 |
-
|
| 69 |
user = relationship("User", back_populates="conversations")
|
| 70 |
messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
|
| 71 |
|
| 72 |
class Message(Base):
|
| 73 |
__tablename__ = "message"
|
| 74 |
-
|
| 75 |
id = Column(Integer, primary_key=True, index=True)
|
| 76 |
-
conversation_id = Column(Integer, ForeignKey("conversation.id"))
|
| 77 |
-
role = Column(String)
|
| 78 |
-
content = Column(
|
| 79 |
-
created_at = Column(DateTime
|
| 80 |
-
|
| 81 |
conversation = relationship("Conversation", back_populates="messages")
|
| 82 |
|
| 83 |
def get_db():
|
|
@@ -87,9 +80,8 @@ def get_db():
|
|
| 87 |
finally:
|
| 88 |
db.close()
|
| 89 |
|
| 90 |
-
# إنشاء الجداول
|
| 91 |
-
Base.metadata.create_all(bind=engine)
|
| 92 |
-
|
| 93 |
-
# دالة للحصول على user database لـ fastapi_users
|
| 94 |
async def get_user_db(session: Session = Depends(get_db)):
|
| 95 |
yield SQLAlchemyUserDatabase(session, User, OAuthAccount)
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
+
from sqlalchemy import Column, String, Integer, ForeignKey, DateTime, Boolean, Text
|
|
|
|
| 3 |
from sqlalchemy.ext.declarative import declarative_base
|
| 4 |
from sqlalchemy.orm import sessionmaker, relationship
|
| 5 |
+
from sqlalchemy import create_engine
|
| 6 |
from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase
|
| 7 |
from sqlalchemy.orm import Session
|
| 8 |
from typing import AsyncGenerator
|
|
|
|
| 12 |
# جلب URL قاعدة البيانات من المتغيرات البيئية
|
| 13 |
SQLALCHEMY_DATABASE_URL = os.getenv("SQLALCHEMY_DATABASE_URL")
|
| 14 |
if not SQLALCHEMY_DATABASE_URL:
|
| 15 |
+
raise ValueError("SQLALCHEMY_DATABASE_URL is not set in environment variables.")
|
| 16 |
|
| 17 |
# إنشاء المحرك
|
| 18 |
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
|
|
|
| 25 |
|
| 26 |
class OAuthAccount(Base):
|
| 27 |
__tablename__ = "oauth_account"
|
|
|
|
| 28 |
id = Column(Integer, primary_key=True, index=True)
|
| 29 |
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
| 30 |
oauth_name = Column(String, nullable=False)
|
|
|
|
| 33 |
refresh_token = Column(String, nullable=True)
|
| 34 |
account_id = Column(String, index=True, nullable=False)
|
| 35 |
account_email = Column(String, nullable=False)
|
|
|
|
| 36 |
user = relationship("User", back_populates="oauth_accounts")
|
| 37 |
|
| 38 |
class User(SQLAlchemyBaseUserTable[int], Base):
|
| 39 |
__tablename__ = "user"
|
|
|
|
| 40 |
id = Column(Integer, primary_key=True, index=True)
|
| 41 |
email = Column(String, unique=True, index=True, nullable=False)
|
| 42 |
hashed_password = Column(String, nullable=False)
|
|
|
|
| 48 |
job_title = Column(String, nullable=True)
|
| 49 |
education = Column(String, nullable=True)
|
| 50 |
interests = Column(String, nullable=True)
|
| 51 |
+
additional_info = Column(Text, nullable=True)
|
| 52 |
conversation_style = Column(String, nullable=True)
|
| 53 |
oauth_accounts = relationship("OAuthAccount", back_populates="user", cascade="all, delete-orphan")
|
| 54 |
+
conversations = relationship("Conversation", back_populates="user", cascade="all, delete-orphan")
|
| 55 |
|
| 56 |
class Conversation(Base):
|
| 57 |
__tablename__ = "conversation"
|
|
|
|
| 58 |
id = Column(Integer, primary_key=True, index=True)
|
| 59 |
+
conversation_id = Column(String, unique=True, index=True, nullable=False)
|
| 60 |
+
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
| 61 |
+
title = Column(String, nullable=False)
|
| 62 |
+
created_at = Column(DateTime, default=datetime.utcnow)
|
| 63 |
+
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
| 64 |
user = relationship("User", back_populates="conversations")
|
| 65 |
messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
|
| 66 |
|
| 67 |
class Message(Base):
|
| 68 |
__tablename__ = "message"
|
|
|
|
| 69 |
id = Column(Integer, primary_key=True, index=True)
|
| 70 |
+
conversation_id = Column(Integer, ForeignKey("conversation.id"), nullable=False)
|
| 71 |
+
role = Column(String, nullable=False)
|
| 72 |
+
content = Column(Text, nullable=False)
|
| 73 |
+
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
| 74 |
conversation = relationship("Conversation", back_populates="messages")
|
| 75 |
|
| 76 |
def get_db():
|
|
|
|
| 80 |
finally:
|
| 81 |
db.close()
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
async def get_user_db(session: Session = Depends(get_db)):
|
| 84 |
yield SQLAlchemyUserDatabase(session, User, OAuthAccount)
|
| 85 |
+
|
| 86 |
+
# إنشاء الجداول
|
| 87 |
+
Base.metadata.create_all(bind=engine)
|
init_db.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
| 1 |
import os
|
|
|
|
| 2 |
from sqlalchemy import create_engine, select, delete
|
| 3 |
from sqlalchemy.orm import sessionmaker
|
| 4 |
from api.database import Base, User, OAuthAccount, Conversation, Message
|
| 5 |
-
import logging
|
| 6 |
|
| 7 |
# Setup logging
|
| 8 |
logging.basicConfig(level=logging.INFO)
|
| 9 |
logger = logging.getLogger(__name__)
|
| 10 |
|
| 11 |
# جلب URL قاعدة البيانات من المتغيرات البيئية
|
| 12 |
-
SQLALCHEMY_DATABASE_URL = os.getenv("SQLALCHEMY_DATABASE_URL")
|
| 13 |
if not SQLALCHEMY_DATABASE_URL:
|
| 14 |
logger.error("SQLALCHEMY_DATABASE_URL is not set in environment variables.")
|
| 15 |
raise ValueError("SQLALCHEMY_DATABASE_URL is required.")
|
|
@@ -29,22 +29,54 @@ def init_db():
|
|
| 29 |
|
| 30 |
# تنظيف البيانات غير المتسقة
|
| 31 |
with SessionLocal() as session:
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
OAuthAccount.
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
user.is_active
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
logger.info("Database initialization completed.")
|
| 50 |
|
|
|
|
| 1 |
import os
|
| 2 |
+
import logging
|
| 3 |
from sqlalchemy import create_engine, select, delete
|
| 4 |
from sqlalchemy.orm import sessionmaker
|
| 5 |
from api.database import Base, User, OAuthAccount, Conversation, Message
|
|
|
|
| 6 |
|
| 7 |
# Setup logging
|
| 8 |
logging.basicConfig(level=logging.INFO)
|
| 9 |
logger = logging.getLogger(__name__)
|
| 10 |
|
| 11 |
# جلب URL قاعدة البيانات من المتغيرات البيئية
|
| 12 |
+
SQLALCHEMY_DATABASE_URL = os.getenv("SQLALCHEMY_DATABASE_URL", "sqlite:///./data/mgzon_users.db")
|
| 13 |
if not SQLALCHEMY_DATABASE_URL:
|
| 14 |
logger.error("SQLALCHEMY_DATABASE_URL is not set in environment variables.")
|
| 15 |
raise ValueError("SQLALCHEMY_DATABASE_URL is required.")
|
|
|
|
| 29 |
|
| 30 |
# تنظيف البيانات غير المتسقة
|
| 31 |
with SessionLocal() as session:
|
| 32 |
+
try:
|
| 33 |
+
# حذف سجلات oauth_accounts اللي مش مرتبطة بمستخدم موجود
|
| 34 |
+
stmt = delete(OAuthAccount).where(
|
| 35 |
+
OAuthAccount.user_id.notin_(select(User.id))
|
| 36 |
+
)
|
| 37 |
+
result = session.execute(stmt)
|
| 38 |
+
deleted_count = result.rowcount
|
| 39 |
+
session.commit()
|
| 40 |
+
logger.info(f"Deleted {deleted_count} orphaned OAuth accounts.")
|
| 41 |
+
|
| 42 |
+
# التأكد من إن كل المستخدمين ليهم is_active=True
|
| 43 |
+
users = session.execute(select(User)).scalars().all()
|
| 44 |
+
for user in users:
|
| 45 |
+
if not user.is_active:
|
| 46 |
+
user.is_active = True
|
| 47 |
+
logger.info(f"Updated user {user.email} to is_active=True")
|
| 48 |
+
session.commit()
|
| 49 |
+
|
| 50 |
+
# اختبار إنشاء مستخدم ومحادثة (اختياري)
|
| 51 |
+
test_user = session.query(User).filter_by(email="test@example.com").first()
|
| 52 |
+
if not test_user:
|
| 53 |
+
test_user = User(
|
| 54 |
+
email="test@example.com",
|
| 55 |
+
hashed_password="$2b$12$examplehashedpassword", # استبدل بكلمة مرور مشفرة حقيقية
|
| 56 |
+
is_active=True,
|
| 57 |
+
display_name="Test User"
|
| 58 |
+
)
|
| 59 |
+
session.add(test_user)
|
| 60 |
+
session.commit()
|
| 61 |
+
logger.info("Test user created successfully.")
|
| 62 |
+
|
| 63 |
+
test_conversation = session.query(Conversation).filter_by(user_id=test_user.id).first()
|
| 64 |
+
if not test_conversation:
|
| 65 |
+
test_conversation = Conversation(
|
| 66 |
+
conversation_id="test-conversation-1",
|
| 67 |
+
user_id=test_user.id,
|
| 68 |
+
title="Test Conversation"
|
| 69 |
+
)
|
| 70 |
+
session.add(test_conversation)
|
| 71 |
+
session.commit()
|
| 72 |
+
logger.info("Test conversation created successfully.")
|
| 73 |
+
|
| 74 |
+
except Exception as e:
|
| 75 |
+
session.rollback()
|
| 76 |
+
logger.error(f"Error during initialization: {e}")
|
| 77 |
+
raise
|
| 78 |
+
finally:
|
| 79 |
+
session.close()
|
| 80 |
|
| 81 |
logger.info("Database initialization completed.")
|
| 82 |
|