101 lines
4.3 KiB
Python
101 lines
4.3 KiB
Python
from datetime import datetime, timezone
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.database import Base
|
|
|
|
|
|
def _utcnow() -> datetime:
|
|
return datetime.now(timezone.utc)
|
|
|
|
|
|
class Recipe(Base):
|
|
__tablename__ = "recipes"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
slug: Mapped[str] = mapped_column(String(255), unique=True, nullable=False, index=True)
|
|
category: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
image_filename: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
|
|
preptime: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
cooktime: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
baketime: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
cooltime: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
marinade_time: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
robot_time: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
servings: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
|
|
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
kcal: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
kh: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
protein: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
fett: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), default=_utcnow, onupdate=_utcnow
|
|
)
|
|
|
|
ingredients: Mapped[list["Ingredient"]] = relationship(
|
|
back_populates="recipe", cascade="all, delete-orphan", order_by="Ingredient.position"
|
|
)
|
|
steps: Mapped[list["Step"]] = relationship(
|
|
back_populates="recipe", cascade="all, delete-orphan", order_by="Step.position"
|
|
)
|
|
book_links: Mapped[list["BookRecipe"]] = relationship(
|
|
back_populates="recipe", cascade="all, delete-orphan"
|
|
)
|
|
|
|
|
|
class Ingredient(Base):
|
|
__tablename__ = "ingredients"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
recipe_id: Mapped[int] = mapped_column(ForeignKey("recipes.id"), nullable=False)
|
|
position: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
kind: Mapped[str] = mapped_column(String(20), nullable=False, default="item") # item | section_header
|
|
quantity: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
unit: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
|
text: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
|
|
recipe: Mapped["Recipe"] = relationship(back_populates="ingredients")
|
|
|
|
|
|
class Step(Base):
|
|
__tablename__ = "steps"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
recipe_id: Mapped[int] = mapped_column(ForeignKey("recipes.id"), nullable=False)
|
|
position: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
text: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
recipe: Mapped["Recipe"] = relationship(back_populates="steps")
|
|
|
|
|
|
class Book(Base):
|
|
__tablename__ = "books"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
recipe_links: Mapped[list["BookRecipe"]] = relationship(
|
|
back_populates="book", cascade="all, delete-orphan"
|
|
)
|
|
|
|
|
|
class BookRecipe(Base):
|
|
__tablename__ = "book_recipes"
|
|
__table_args__ = (UniqueConstraint("book_id", "recipe_id", name="uq_book_recipe"),)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
book_id: Mapped[int] = mapped_column(ForeignKey("books.id"), nullable=False)
|
|
recipe_id: Mapped[int] = mapped_column(ForeignKey("recipes.id"), nullable=False)
|
|
chapter: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
position: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
|
|
book: Mapped["Book"] = relationship(back_populates="recipe_links")
|
|
recipe: Mapped["Recipe"] = relationship(back_populates="book_links")
|