Coverage for opt/mealie/lib/python3.12/site-packages/mealie/db/models/recipe/tool.py: 89%
34 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
1from typing import TYPE_CHECKING
3from pydantic import ConfigDict
4from slugify import slugify
5from sqlalchemy import Boolean, Column, ForeignKey, String, Table, UniqueConstraint, orm
6from sqlalchemy.orm import Mapped, mapped_column
8from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase
9from mealie.db.models._model_utils.auto_init import auto_init
10from mealie.db.models._model_utils.guid import GUID
12if TYPE_CHECKING: 12 ↛ 13line 12 didn't jump to line 13 because the condition on line 12 was never true
13 from ..group import Group
14 from ..household import Household
15 from . import RecipeModel
17households_to_tools = Table(
18 "households_to_tools",
19 SqlAlchemyBase.metadata,
20 Column("household_id", GUID, ForeignKey("households.id"), index=True),
21 Column("tool_id", GUID, ForeignKey("tools.id"), index=True),
22 UniqueConstraint("household_id", "tool_id", name="household_id_tool_id_key"),
23)
25recipes_to_tools = Table(
26 "recipes_to_tools",
27 SqlAlchemyBase.metadata,
28 Column("recipe_id", GUID, ForeignKey("recipes.id"), index=True),
29 Column("tool_id", GUID, ForeignKey("tools.id"), index=True),
30 UniqueConstraint("recipe_id", "tool_id", name="recipe_id_tool_id_key"),
31)
33cookbooks_to_tools = Table(
34 "cookbooks_to_tools",
35 SqlAlchemyBase.metadata,
36 Column("cookbook_id", GUID, ForeignKey("cookbooks.id"), index=True),
37 Column("tool_id", GUID, ForeignKey("tools.id"), index=True),
38 UniqueConstraint("cookbook_id", "tool_id", name="cookbook_id_tool_id_key"),
39)
42class Tool(SqlAlchemyBase, BaseMixins):
43 __tablename__ = "tools"
44 __table_args__ = (UniqueConstraint("slug", "group_id", name="tools_slug_group_id_key"),)
45 id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
47 # ID Relationships
48 group_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("groups.id"), nullable=False, index=True)
49 group: Mapped["Group"] = orm.relationship("Group", back_populates="tools", foreign_keys=[group_id])
51 name: Mapped[str] = mapped_column(String, index=True, nullable=False)
52 slug: Mapped[str] = mapped_column(String, index=True, nullable=False)
54 households_with_tool: Mapped[list["Household"]] = orm.relationship(
55 "Household", secondary=households_to_tools, back_populates="tools_on_hand"
56 )
57 recipes: Mapped[list["RecipeModel"]] = orm.relationship(
58 "RecipeModel", secondary=recipes_to_tools, back_populates="tools"
59 )
61 model_config = ConfigDict(
62 exclude={
63 "households_with_tool",
64 }
65 )
67 # Deprecated
68 on_hand: Mapped[bool | None] = mapped_column(Boolean, default=False)
70 @auto_init()
71 def __init__(
72 self, session: orm.Session, group_id: GUID, name: str, households_with_tool: list[str] | None = None, **_
73 ) -> None:
74 from ..household import Household
76 self.slug = slugify(name)
78 if not households_with_tool:
79 self.households_with_tool = []
80 else:
81 self.households_with_tool = (
82 session.query(Household)
83 .filter(Household.group_id == group_id, Household.slug.in_(households_with_tool))
84 .all()
85 )