linkedin2/model/database.py

111 lines
4.6 KiB
Python
Raw Normal View History

2025-02-17 18:18:14 +02:00
from sqlalchemy import Column, Integer, String, Text, DateTime, Float, Boolean, BigInteger
from sqlalchemy.dialects.mysql import JSON
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy.sql import func
from passlib.context import CryptContext
from dotenv import load_dotenv
from sqlalchemy.future import select
import os
# Загружаем переменные окружения
load_dotenv()
# Правильная строка подключения
DATABASE_URL = os.getenv('DATABASE_URL') # Должно быть "mysql+aiomysql://..." или "postgresql+asyncpg://..."
# Создаём асинхронный движок
async_engine = create_async_engine(DATABASE_URL, echo=True)
# Создаём фабрику сессий
async_session = sessionmaker(async_engine, class_=AsyncSession, expire_on_commit=False)
# Базовый класс для моделей
Base = declarative_base()
# Контекст хеширования паролей
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# Функция для инициализации базы данных
async def init_db():
async with async_engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async with async_session() as session:
# Проверяем, есть ли уже данные в таблице пользователей
result = await session.execute(select(User).limit(1))
user_exists = result.scalars().first()
if not user_exists:
new_user = User(
username="admin",
hashed_password=hash_password("admin123"), # Пароль хешируем
role="admin",
is_active=True
)
session.add(new_user)
await session.commit()
# Зависимость FastAPI для работы с БД
async def get_async_session() -> AsyncSession:
async with async_session() as session:
yield session
# Функции для хеширования паролей
def hash_password(password: str) -> str:
return pwd_context.hash(password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
# async def get_db():
# async with SessionLocal() as session:
# yield session
# Модель пользователя
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String(55), unique=True, index=True, nullable=False) # ✅ Правильно
hashed_password = Column(String(255), nullable=False)
role = Column(String(55), default="user")
is_active = Column(Boolean, default=True)
# Модель профиля
class Profile(Base):
__tablename__ = "profile"
id = Column(Integer, primary_key=True, index=True)
link = Column(String(255), unique=True, nullable=True)
first_name = Column(String(255), nullable=False)
last_name = Column(String(255), nullable=False)
pronouns = Column(String(50), nullable=True)
email = Column(String(255), nullable=True)
telephone = Column(String(20), nullable=True)
location = Column(String(255), nullable=True)
statement = Column(Text, nullable=True)
skills = Column(JSON, nullable=True) # JSON-поле для списка навыков
websites = Column(JSON, nullable=True) # JSON-поле для списка сайтов
languages = Column(JSON, nullable=True) # JSON-поле для языков
date = Column(DateTime, server_default=func.now())
# Модель вакансий
class Job(Base):
__tablename__ = "jobs"
job_id = Column(BigInteger, primary_key=True, index=True)
job_title = Column(String(255), nullable=False)
job_company = Column(String(255), nullable=True)
minimum_annual_salary = Column(Float, nullable=True)
salary_currency = Column(String(10), nullable=True)
location_type = Column(String(50), nullable=True) # Remote, On-site, Hybrid
location = Column(String(255), nullable=True)
job_level = Column(String(50), nullable=True) # Entry-level, Junior, Mid
job_type = Column(String(50), nullable=True) # Full-time, Part-time
days_posted = Column(Integer, nullable=True)
hourly_rate = Column(Float, nullable=True)
link = Column(String(2083), nullable=True) # URL вакансии
link_company = Column(String(2083), nullable=True) # URL компании
active = Column(Boolean, default=True) # Вакансия активна?