Coverage for opt/mealie/lib/python3.12/site-packages/mealie/db/models/household/household.py: 88%
39 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
3import sqlalchemy as sa
4import sqlalchemy.orm as orm
5from pydantic import ConfigDict
6from sqlalchemy.orm import Mapped, mapped_column
8from .._model_base import BaseMixins, SqlAlchemyBase
9from .._model_utils.auto_init import auto_init
10from .._model_utils.guid import GUID
11from ..recipe.ingredient import households_to_ingredient_foods
12from ..recipe.tool import households_to_tools
13from .household_to_recipe import HouseholdToRecipe
15if TYPE_CHECKING: 15 ↛ 16line 15 didn't jump to line 16 because the condition on line 15 was never true
16 from ..group import Group
17 from ..recipe import IngredientFoodModel, RecipeModel, Tool
18 from ..users import User
19 from . import (
20 CookBook,
21 GroupEventNotifierModel,
22 GroupInviteToken,
23 GroupRecipeAction,
24 GroupWebhooksModel,
25 HouseholdPreferencesModel,
26 )
29class Household(SqlAlchemyBase, BaseMixins):
30 __tablename__ = "households"
31 __table_args__ = (
32 sa.UniqueConstraint("group_id", "name", name="household_name_group_id_key"),
33 sa.UniqueConstraint("group_id", "slug", name="household_slug_group_id_key"),
34 )
36 id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
37 name: Mapped[str] = mapped_column(sa.String, index=True, nullable=False)
38 slug: Mapped[str | None] = mapped_column(sa.String, index=True)
40 invite_tokens: Mapped[list["GroupInviteToken"]] = orm.relationship(
41 "GroupInviteToken", back_populates="household", cascade="all, delete-orphan"
42 )
43 preferences: Mapped["HouseholdPreferencesModel"] = orm.relationship(
44 "HouseholdPreferencesModel",
45 back_populates="household",
46 uselist=False,
47 single_parent=True,
48 cascade="all, delete-orphan",
49 )
51 group_id: Mapped[GUID] = mapped_column(GUID, sa.ForeignKey("groups.id"), nullable=False, index=True)
52 group: Mapped["Group"] = orm.relationship("Group", back_populates="households")
53 users: Mapped[list["User"]] = orm.relationship("User", back_populates="household")
55 COMMON_ARGS = {
56 "back_populates": "household",
57 "cascade": "all, delete-orphan",
58 "single_parent": True,
59 }
61 recipe_actions: Mapped[list["GroupRecipeAction"]] = orm.relationship("GroupRecipeAction", **COMMON_ARGS)
62 cookbooks: Mapped[list["CookBook"]] = orm.relationship("CookBook", **COMMON_ARGS)
64 webhooks: Mapped[list["GroupWebhooksModel"]] = orm.relationship("GroupWebhooksModel", **COMMON_ARGS)
65 group_event_notifiers: Mapped[list["GroupEventNotifierModel"]] = orm.relationship(
66 "GroupEventNotifierModel", **COMMON_ARGS
67 )
69 made_recipes: Mapped[list["RecipeModel"]] = orm.relationship(
70 "RecipeModel", secondary=HouseholdToRecipe.__tablename__, back_populates="made_by"
71 )
72 ingredient_foods_on_hand: Mapped[list["IngredientFoodModel"]] = orm.relationship(
73 "IngredientFoodModel",
74 secondary=households_to_ingredient_foods,
75 back_populates="households_with_ingredient_food",
76 )
77 tools_on_hand: Mapped[list["Tool"]] = orm.relationship(
78 "Tool", secondary=households_to_tools, back_populates="households_with_tool"
79 )
81 model_config = ConfigDict(
82 exclude={
83 "users",
84 "webhooks",
85 "recipe_actions",
86 "cookbooks",
87 "preferences",
88 "invite_tokens",
89 "group_event_notifiers",
90 "group",
91 "made_recipes",
92 }
93 )
95 @auto_init()
96 def __init__(self, **_) -> None:
97 pass