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.models import User, Book, Author, Genre, Favorite
from database.models import User, Book, Author, Genre, Favorite, UserPreferences
__all__ = [
'get_session',
@@ -10,6 +10,7 @@ __all__ = [
'Book',
'Author',
'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 datetime import datetime
from datetime import datetime, date
from typing import Optional, List
@@ -12,43 +12,70 @@ class Base(DeclarativeBase):
books_book_authors = Table(
'books_book_authors',
Base.metadata,
Column('id', Integer, primary_key=True),
Column('book_id', Integer, ForeignKey('books_book.id')),
Column('author_id', Integer, ForeignKey('books_author.id'))
Column('id', BigInteger, primary_key=True),
Column('book_id', BigInteger, ForeignKey('books_book.id')),
Column('author_id', BigInteger, ForeignKey('books_author.id'))
)
books_book_genres = Table(
'books_book_genres',
Base.metadata,
Column('id', Integer, primary_key=True),
Column('book_id', Integer, ForeignKey('books_book.id')),
Column('genre_id', Integer, ForeignKey('books_genre.id'))
Column('id', BigInteger, primary_key=True),
Column('book_id', BigInteger, ForeignKey('books_book.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):
__tablename__ = 'auth_user'
"""
Модель пользователя из Django приложения 'users'
Таблица: users_user
"""
__tablename__ = 'users_user'
id: Mapped[int] = mapped_column(Integer, primary_key=True)
username: Mapped[str] = mapped_column(String(150), unique=True)
email: Mapped[str] = mapped_column(String(254), unique=True)
# Стандартные поля Django AbstractUser
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
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)
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")
favorite_genres: Mapped[List["Genre"]] = relationship(
secondary=users_user_favorite_genres,
back_populates="users"
)
class Author(Base):
__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))
books: Mapped[List["Book"]] = relationship(secondary=books_book_authors, back_populates="authors")
@@ -57,24 +84,28 @@ class Author(Base):
class Genre(Base):
__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))
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):
__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))
description: Mapped[Optional[str]] = mapped_column(Text, 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)
rating_count: Mapped[int] = mapped_column(Integer, default=0)
language: Mapped[Optional[str]] = mapped_column(String(10), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
created_at: Mapped[datetime] = mapped_column(DateTime)
updated_at: Mapped[datetime] = mapped_column(DateTime)
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
authors: Mapped[List[Author]] = relationship(secondary=books_book_authors, back_populates="books")
@@ -85,11 +116,30 @@ class Book(Base):
class Favorite(Base):
__tablename__ = 'books_favorite'
id: Mapped[int] = mapped_column(Integer, primary_key=True)
user_id: Mapped[int] = mapped_column(Integer, ForeignKey('auth_user.id'))
book_id: Mapped[int] = mapped_column(Integer, ForeignKey('books_book.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey('users_user.id'))
book_id: Mapped[int] = mapped_column(BigInteger, ForeignKey('books_book.id'))
created_at: Mapped[datetime] = mapped_column(DateTime)
user: Mapped[User] = 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)