Spaces:
Runtime error
Runtime error
File size: 6,481 Bytes
339f372 |
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
from datetime import datetime
from typing import Optional
from sqlalchemy import BigInteger, String, ForeignKey, Integer, DateTime, Boolean
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine
from app.config.config import DATABASE_URL
engine = create_async_engine(DATABASE_URL) # подключение и создание БД
async_session = async_sessionmaker(engine, expire_on_commit=False)
class Base(AsyncAttrs, DeclarativeBase):
"""Base class for all models"""
pass
class User(Base):
"""User model for storing telegram user data"""
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
tg_id: Mapped[int] = mapped_column(BigInteger, unique=True, nullable=False)
name: Mapped[str] = mapped_column(String(100), nullable=True)
login: Mapped[str] = mapped_column(String(100), nullable=True)
contact: Mapped[str] = mapped_column(String(100), nullable=True)
subscription_status: Mapped[str] = mapped_column(
String(20), default='inactive')
# Relationships
test_attempts = relationship("TestAttempt", back_populates="user")
feedback = relationship("Feedback", back_populates="user")
class Service(Base):
"""Service model for storing available services"""
__tablename__ = 'services'
id: Mapped[int] = mapped_column(primary_key=True)
service_name: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
service_description: Mapped[str] = mapped_column(String(500))
service_price: Mapped[int] = mapped_column(BigInteger, nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
# Relationships
feedback = relationship("Feedback", back_populates="service")
class Test(Base):
"""Test model for storing quiz/test information"""
__tablename__ = 'tests'
id: Mapped[int] = mapped_column(primary_key=True)
test_name: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
test_type: Mapped[str] = mapped_column(String(20), nullable=False)
test_description: Mapped[str] = mapped_column(String(250))
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
completion_message: Mapped[Optional[str]] = mapped_column(String(1000))
# Relationships
questions = relationship("TestQuestion", back_populates="test", cascade="all, delete-orphan")
results = relationship("TestResult", back_populates="test", cascade="all, delete-orphan")
attempts = relationship("TestAttempt", back_populates="test")
class TestQuestion(Base):
"""Model for storing test questions"""
__tablename__ = 'test_questions'
id: Mapped[int] = mapped_column(primary_key=True)
test_id: Mapped[int] = mapped_column(ForeignKey('tests.id', ondelete='CASCADE'), nullable=False)
question_content: Mapped[str] = mapped_column(String(150), nullable=False)
question_variants: Mapped[str] = mapped_column(String(500), nullable=False) # JSON string
question_points: Mapped[str] = mapped_column(String(100), nullable=False) # JSON string
# Relationships
test = relationship("Test", back_populates="questions")
class TestResult(Base):
"""Model for storing possible test results"""
__tablename__ = 'test_results'
id: Mapped[int] = mapped_column(primary_key=True)
test_id: Mapped[int] = mapped_column(ForeignKey('tests.id', ondelete='CASCADE'), nullable=False)
min_points: Mapped[int] = mapped_column(Integer, nullable=False)
max_points: Mapped[int] = mapped_column(Integer, nullable=False)
result_text: Mapped[str] = mapped_column(String(1000), nullable=False)
# Relationships
test = relationship("Test", back_populates="results")
class TestAttempt(Base):
"""Model for storing user test attempts"""
__tablename__ = 'test_attempts'
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
test_id: Mapped[int] = mapped_column(ForeignKey('tests.id', ondelete='CASCADE'), nullable=False)
score: Mapped[int] = mapped_column(Integer, nullable=True)
result: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
completed_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, nullable=True)
# Relationships
user = relationship("User", back_populates="test_attempts")
test = relationship("Test", back_populates="attempts")
class TestAnswer(Base):
"""Stores individual answers for each question"""
__tablename__ = 'test_answers'
id: Mapped[int] = mapped_column(primary_key=True)
attempt_id: Mapped[int] = mapped_column(ForeignKey('test_attempts.id', ondelete='CASCADE'))
question_id: Mapped[int] = mapped_column(ForeignKey('test_questions.id', ondelete='CASCADE'))
answer_given: Mapped[str] = mapped_column(String(500))
points_earned: Mapped[int] = mapped_column(Integer, nullable=True)
class LeadMagnet(Base):
"""Model for storing lead magnets/content triggers"""
__tablename__ = 'lead_magnets'
id: Mapped[int] = mapped_column(primary_key=True)
trigger: Mapped[str] = mapped_column(String(50), unique=True, nullable=False)
content: Mapped[str] = mapped_column(String(500), nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
class Feedback(Base):
"""Model for storing user feedback"""
__tablename__ = 'feedback'
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
service_id: Mapped[int] = mapped_column(ForeignKey('services.id', ondelete='CASCADE'), nullable=False)
rating: Mapped[int] = mapped_column(Integer, nullable=False)
review: Mapped[str] = mapped_column(String(1000))
is_new: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
# Relationships
user = relationship("User", back_populates="feedback")
service = relationship("Service", back_populates="feedback")
async def async_main():
"""Initialize database tables"""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all) |