/
Askoline
/
Homework03
Обзор
Документация
Войти
/
Askoline
/
Homework03
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
models.py
189 строк
7 KB
Askoline
first_commit
05 авг 2026, 14:29
05 авг 2026, 14:29
a97374b
Код
Авторство
О чём код?
# -*- coding: utf-8 -*- # models.py # Модели SQLAlchemy для системы учета продаж книг from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, create_engine from sqlalchemy.orm import relationship, declarative_base, sessionmaker from datetime import datetime # Создаем базовый класс для моделей Base = declarative_base() class Publisher(Base): """ Модель издателя (автора/издательства) Атрибуты: id (int): Уникальный идентификатор name (str): Название издателя books (List[Book]): Список книг этого издателя """ __tablename__ = 'publisher' id = Column(Integer, primary_key=True, index=True) name = Column(String(255), nullable=False, unique=True) # Отношение "один ко многим" с книгами books = relationship("Book", back_populates="publisher", cascade="all, delete-orphan") def __repr__(self) -> str: return f"<Publisher(id={self.id}, name='{self.name}')>" def __str__(self) -> str: return self.name class Book(Base): """ Модель книги Атрибуты: id (int): Уникальный идентификатор title (str): Название книги id_publisher (int): ID издателя (внешний ключ) publisher (Publisher): Объект издателя stocks (List[Stock]): Записи о наличии книги в магазинах """ __tablename__ = 'book' id = Column(Integer, primary_key=True, index=True) title = Column(String(255), nullable=False) id_publisher = Column(Integer, ForeignKey('publisher.id', ondelete='CASCADE'), nullable=False) # Отношения publisher = relationship("Publisher", back_populates="books") stocks = relationship("Stock", back_populates="book", cascade="all, delete-orphan") def __repr__(self) -> str: return f"<Book(id={self.id}, title='{self.title}', publisher_id={self.id_publisher})>" def __str__(self) -> str: return f"{self.title} ({self.publisher.name if self.publisher else 'No publisher'})" class Shop(Base): """ Модель магазина Атрибуты: id (int): Уникальный идентификатор name (str): Название магазина stocks (List[Stock]): Записи о наличии книг в этом магазине """ __tablename__ = 'shop' id = Column(Integer, primary_key=True, index=True) name = Column(String(255), nullable=False, unique=True) # Отношение с остатками stocks = relationship("Stock", back_populates="shop", cascade="all, delete-orphan") def __repr__(self) -> str: return f"<Shop(id={self.id}, name='{self.name}')>" def __str__(self) -> str: return self.name class Stock(Base): """ Модель остатков книг на складах магазинов Атрибуты: id (int): Уникальный идентификатор id_book (int): ID книги id_shop (int): ID магазина count (int): Количество книг в наличии book (Book): Объект книги shop (Shop): Объект магазина sales (List[Sale]): Продажи по этому остатку """ __tablename__ = 'stock' id = Column(Integer, primary_key=True, index=True) id_book = Column(Integer, ForeignKey('book.id', ondelete='CASCADE'), nullable=False) id_shop = Column(Integer, ForeignKey('shop.id', ondelete='CASCADE'), nullable=False) count = Column(Integer, nullable=False, default=0) # Отношения book = relationship("Book", back_populates="stocks") shop = relationship("Shop", back_populates="stocks") sales = relationship("Sale", back_populates="stock", cascade="all, delete-orphan") def __repr__(self) -> str: return f"<Stock(id={self.id}, book_id={self.id_book}, shop_id={self.id_shop}, count={self.count})>" def reduce_count(self, amount: int) -> bool: """ Уменьшить количество книг на складе Args: amount: Количество для списания Returns: bool: True если списание успешно, False если недостаточно книг """ if self.count >= amount: self.count -= amount return True return False class Sale(Base): """ Модель продажи книги Атрибуты: id (int): Уникальный идентификатор id_stock (int): ID записи об остатке count (int): Количество проданных книг price (float): Цена за единицу на момент продажи date_sale (datetime): Дата и время продажи stock (Stock): Объект остатка """ __tablename__ = 'sale' id = Column(Integer, primary_key=True, index=True) id_stock = Column(Integer, ForeignKey('stock.id', ondelete='CASCADE'), nullable=False) count = Column(Integer, nullable=False) price = Column(Float, nullable=False) date_sale = Column(DateTime, default=datetime.utcnow, nullable=False) # Отношение с остатком stock = relationship("Stock", back_populates="sales") @property def total_amount(self) -> float: """Общая сумма продажи""" return self.count * self.price def __repr__(self) -> str: return f"<Sale(id={self.id}, stock_id={self.id_stock}, count={self.count}, price={self.price}, date={self.date_sale})>" # Функция для создания подключения к базе данных def get_engine(db_url: str = "sqlite:///bookstore.db"): """ Создает движок SQLAlchemy Args: db_url: Строка подключения к БД Returns: Engine: Движок SQLAlchemy """ return create_engine(db_url, echo=True) # Функция для создания таблиц def create_tables(engine): """Создает все таблицы в базе данных""" Base.metadata.create_all(engine) # Функция для получения сессии def get_session(engine): """Создает и возвращает сессию для работы с БД""" Session = sessionmaker(bind=engine) return Session()