This commit is contained in:
2025-12-25 16:32:17 +03:00
parent 58827ac124
commit dac7d95be4
2 changed files with 81 additions and 30 deletions

View File

@@ -1,6 +1,6 @@
"""Модуль для работы с базой данных""" """Модуль для работы с базой данных"""
from database.connection import get_session, async_session_maker, engine from database.connection import get_session, async_session_maker, engine
from database.models import User, Book, Author, Genre, Favorite from database.models import User, Book, Author, Genre, Favorite, UserPreferences
__all__ = [ __all__ = [
'get_session', 'get_session',
@@ -10,6 +10,7 @@ __all__ = [
'Book', 'Book',
'Author', 'Author',
'Genre', 'Genre',
'Favorite' 'Favorite',
'UserPreferences'
] ]

View File

@@ -1,6 +1,6 @@
from sqlalchemy import BigInteger, String, Text, Numeric, Integer, DateTime, Boolean, ForeignKey, Table, Column from sqlalchemy import BigInteger, String, Text, Numeric, Integer, DateTime, Boolean, ForeignKey, Table, Column, Date
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from datetime import datetime from datetime import datetime, date
from typing import Optional, List from typing import Optional, List
@@ -12,43 +12,70 @@ class Base(DeclarativeBase):
books_book_authors = Table( books_book_authors = Table(
'books_book_authors', 'books_book_authors',
Base.metadata, Base.metadata,
Column('id', Integer, primary_key=True), Column('id', BigInteger, primary_key=True),
Column('book_id', Integer, ForeignKey('books_book.id')), Column('book_id', BigInteger, ForeignKey('books_book.id')),
Column('author_id', Integer, ForeignKey('books_author.id')) Column('author_id', BigInteger, ForeignKey('books_author.id'))
) )
books_book_genres = Table( books_book_genres = Table(
'books_book_genres', 'books_book_genres',
Base.metadata, Base.metadata,
Column('id', Integer, primary_key=True), Column('id', BigInteger, primary_key=True),
Column('book_id', Integer, ForeignKey('books_book.id')), Column('book_id', BigInteger, ForeignKey('books_book.id')),
Column('genre_id', Integer, ForeignKey('books_genre.id')) Column('genre_id', BigInteger, ForeignKey('books_genre.id'))
)
# Many-to-Many для любимых жанров пользователя
users_user_favorite_genres = Table(
'users_user_favorite_genres',
Base.metadata,
Column('id', BigInteger, primary_key=True),
Column('user_id', BigInteger, ForeignKey('users_user.id')),
Column('genre_id', BigInteger, ForeignKey('books_genre.id'))
) )
class User(Base): class User(Base):
__tablename__ = 'auth_user' """
Модель пользователя из Django приложения 'users'
Таблица: users_user
"""
__tablename__ = 'users_user'
id: Mapped[int] = mapped_column(Integer, primary_key=True) # Стандартные поля Django AbstractUser
username: Mapped[str] = mapped_column(String(150), unique=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
email: Mapped[str] = mapped_column(String(254), unique=True)
password: Mapped[str] = mapped_column(String(128)) password: Mapped[str] = mapped_column(String(128))
telegram_id: Mapped[Optional[int]] = mapped_column(BigInteger, unique=True, nullable=True)
first_name: Mapped[Optional[str]] = mapped_column(String(150), nullable=True)
last_name: Mapped[Optional[str]] = mapped_column(String(150), nullable=True)
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
is_staff: Mapped[bool] = mapped_column(Boolean, default=False)
is_superuser: Mapped[bool] = mapped_column(Boolean, default=False)
date_joined: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
last_login: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) last_login: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
is_superuser: Mapped[bool] = mapped_column(Boolean, default=False)
username: Mapped[str] = mapped_column(String(150), unique=True)
first_name: Mapped[str] = mapped_column(String(150), default='')
last_name: Mapped[str] = mapped_column(String(150), default='')
email: Mapped[str] = mapped_column(String(254), unique=True)
is_staff: Mapped[bool] = mapped_column(Boolean, default=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
date_joined: Mapped[datetime] = mapped_column(DateTime)
# Дополнительные поля из модели users.User
phone: Mapped[str] = mapped_column(String(20), default='')
avatar: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
birth_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
about: Mapped[str] = mapped_column(Text, default='')
telegram_id: Mapped[Optional[int]] = mapped_column(BigInteger, unique=True, nullable=True)
is_verified: Mapped[bool] = mapped_column(Boolean, default=False)
last_activity: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
# Relationships
favorites: Mapped[List["Favorite"]] = relationship(back_populates="user") favorites: Mapped[List["Favorite"]] = relationship(back_populates="user")
favorite_genres: Mapped[List["Genre"]] = relationship(
secondary=users_user_favorite_genres,
back_populates="users"
)
class Author(Base): class Author(Base):
__tablename__ = 'books_author' __tablename__ = 'books_author'
id: Mapped[int] = mapped_column(Integer, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
name: Mapped[str] = mapped_column(String(255)) name: Mapped[str] = mapped_column(String(255))
books: Mapped[List["Book"]] = relationship(secondary=books_book_authors, back_populates="authors") books: Mapped[List["Book"]] = relationship(secondary=books_book_authors, back_populates="authors")
@@ -57,24 +84,28 @@ class Author(Base):
class Genre(Base): class Genre(Base):
__tablename__ = 'books_genre' __tablename__ = 'books_genre'
id: Mapped[int] = mapped_column(Integer, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
name: Mapped[str] = mapped_column(String(100)) name: Mapped[str] = mapped_column(String(100))
books: Mapped[List["Book"]] = relationship(secondary=books_book_genres, back_populates="genres") books: Mapped[List["Book"]] = relationship(secondary=books_book_genres, back_populates="genres")
users: Mapped[List[User]] = relationship(
secondary=users_user_favorite_genres,
back_populates="favorite_genres"
)
class Book(Base): class Book(Base):
__tablename__ = 'books_book' __tablename__ = 'books_book'
id: Mapped[int] = mapped_column(Integer, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
title: Mapped[str] = mapped_column(String(500)) title: Mapped[str] = mapped_column(String(500))
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
cover_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True) cover_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
average_rating: Mapped[Optional[float]] = mapped_column(Numeric(3, 2), nullable=True) average_rating: Mapped[Optional[float]] = mapped_column(Numeric(3, 2), nullable=True)
rating_count: Mapped[int] = mapped_column(Integer, default=0) rating_count: Mapped[int] = mapped_column(Integer, default=0)
language: Mapped[Optional[str]] = mapped_column(String(10), nullable=True) language: Mapped[Optional[str]] = mapped_column(String(10), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) created_at: Mapped[datetime] = mapped_column(DateTime)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime)
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
authors: Mapped[List[Author]] = relationship(secondary=books_book_authors, back_populates="books") authors: Mapped[List[Author]] = relationship(secondary=books_book_authors, back_populates="books")
@@ -85,11 +116,30 @@ class Book(Base):
class Favorite(Base): class Favorite(Base):
__tablename__ = 'books_favorite' __tablename__ = 'books_favorite'
id: Mapped[int] = mapped_column(Integer, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
user_id: Mapped[int] = mapped_column(Integer, ForeignKey('auth_user.id')) user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey('users_user.id'))
book_id: Mapped[int] = mapped_column(Integer, ForeignKey('books_book.id')) book_id: Mapped[int] = mapped_column(BigInteger, ForeignKey('books_book.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) created_at: Mapped[datetime] = mapped_column(DateTime)
user: Mapped[User] = relationship(back_populates="favorites") user: Mapped[User] = relationship(back_populates="favorites")
book: Mapped[Book] = relationship(back_populates="favorites") book: Mapped[Book] = relationship(back_populates="favorites")
class UserPreferences(Base):
"""
Настройки пользователя из Django приложения 'users'
Таблица: users_userpreferences
"""
__tablename__ = 'users_userpreferences'
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey('users_user.id'), unique=True)
created_at: Mapped[datetime] = mapped_column(DateTime)
updated_at: Mapped[datetime] = mapped_column(DateTime)
language: Mapped[str] = mapped_column(String(10), default='ru')
theme: Mapped[str] = mapped_column(String(20), default='light')
email_notifications: Mapped[bool] = mapped_column(Boolean, default=True)
telegram_notifications: Mapped[bool] = mapped_column(Boolean, default=False)
show_email: Mapped[bool] = mapped_column(Boolean, default=False)
show_phone: Mapped[bool] = mapped_column(Boolean, default=False)