Coverage for opt/mealie/lib/python3.12/site-packages/mealie/services/migrations/utils/database_helpers.py: 49%

29 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-11-25 15:48 +0000

1from __future__ import annotations 1a

2 

3from collections.abc import Iterable 1a

4from typing import TYPE_CHECKING 1a

5 

6from pydantic import BaseModel 1a

7from slugify import slugify 1a

8from sqlalchemy.orm import Session 1a

9 

10from mealie.repos.all_repositories import AllRepositories 1a

11from mealie.schema.recipe import RecipeCategory 1a

12from mealie.schema.recipe.recipe import RecipeTag 1a

13from mealie.schema.recipe.recipe_category import CategoryOut, CategorySave, TagOut, TagSave 1a

14 

15if TYPE_CHECKING: 15 ↛ 16line 15 didn't jump to line 16 because the condition on line 15 was never true1a

16 from mealie.repos.repository_generic import RepositoryGeneric 

17 

18 

19class DatabaseMigrationHelpers: 1a

20 def __init__(self, db: AllRepositories, session: Session) -> None: 1a

21 self.session = session 

22 self.db = db 

23 

24 def _get_or_set_generic[T: BaseModel]( 1a

25 self, accessor: RepositoryGeneric, items: Iterable[str], create_model: type[T], out_model: type[T] 

26 ) -> list[T]: 

27 """ 

28 Utility model for getting or setting categories or tags. This will only work for those two cases. 

29 

30 This is probably a bad implementation of this pattern. 

31 """ 

32 items_out = [] 

33 

34 for item_name in items: 

35 slug_lookup = slugify(item_name) 

36 

37 item_model = accessor.get_one(value=slug_lookup, key="slug", override_schema=out_model) 

38 

39 if not item_model: 

40 item_model = accessor.create( 

41 create_model( 

42 group_id=self.db.group_id, 

43 name=item_name, 

44 slug=slug_lookup, 

45 ) 

46 ) 

47 

48 items_out.append(item_model.model_dump()) 

49 return items_out 

50 

51 def get_or_set_category(self, categories: Iterable[str]) -> list[RecipeCategory]: 1a

52 return self._get_or_set_generic( 

53 self.db.categories, 

54 categories, 

55 CategorySave, 

56 CategoryOut, 

57 ) 

58 

59 def get_or_set_tags(self, tags: Iterable[str]) -> list[RecipeTag]: 1a

60 return self._get_or_set_generic( 

61 self.db.tags, 

62 tags, 

63 TagSave, 

64 TagOut, 

65 )