Coverage for opt/mealie/lib/python3.12/site-packages/mealie/alembic/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py: 64%

71 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-12-05 14:03 +0000

1"""add normalized search properties 

2 

3Revision ID: 5ab195a474eb 

4Revises: 16160bf731a0 

5Create Date: 2023-02-14 20:45:41.102571 

6 

7""" 

8 

9import sqlalchemy as sa 1a

10from sqlalchemy import orm, select 1a

11from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column 1a

12from text_unidecode import unidecode 1a

13 

14from alembic import op 1a

15from mealie.db.models._model_utils.guid import GUID 1a

16 

17# revision identifiers, used by Alembic. 

18revision = "5ab195a474eb" 1a

19down_revision = "16160bf731a0" 1a

20branch_labels: str | tuple[str, ...] | None = None 1a

21depends_on: str | tuple[str, ...] | None = None 1a

22 

23 

24class SqlAlchemyBase(DeclarativeBase): 1a

25 pass 1a

26 

27 

28# Intermediate table definitions 

29class RecipeModel(SqlAlchemyBase): 1a

30 __tablename__ = "recipes" 1a

31 

32 id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate) 1a

33 name: Mapped[str] = mapped_column(sa.String, nullable=False) 1a

34 description: Mapped[str | None] = mapped_column(sa.String) 1a

35 name_normalized: Mapped[str] = mapped_column(sa.String, nullable=False, index=True) 1a

36 description_normalized: Mapped[str | None] = mapped_column(sa.String, index=True) 1a

37 

38 

39class RecipeIngredient(SqlAlchemyBase): 1a

40 __tablename__ = "recipes_ingredients" 1a

41 

42 id: Mapped[int] = mapped_column(sa.Integer, primary_key=True) 1a

43 note: Mapped[str | None] = mapped_column(sa.String) 1a

44 original_text: Mapped[str | None] = mapped_column(sa.String) 1a

45 note_normalized: Mapped[str | None] = mapped_column(sa.String, index=True) 1a

46 original_text_normalized: Mapped[str | None] = mapped_column(sa.String, index=True) 1a

47 

48 

49def do_data_migration(): 1a

50 bind = op.get_bind() 1a

51 session = orm.Session(bind=bind) 1a

52 

53 recipes = session.execute(select(RecipeModel)).scalars().all() 1a

54 for recipe in recipes: 54 ↛ 55line 54 didn't jump to line 55 because the loop on line 54 never started1a

55 if recipe.name is not None: 

56 session.execute( 

57 sa.text( 

58 f"UPDATE {RecipeModel.__tablename__} SET name_normalized=:name_normalized WHERE id=:id" 

59 ).bindparams(name_normalized=unidecode(recipe.name).lower().strip(), id=recipe.id) 

60 ) 

61 

62 if recipe.description is not None: 

63 session.execute( 

64 sa.text( 

65 f"UPDATE {RecipeModel.__tablename__} SET description_normalized=:description_normalized WHERE id=:id" 

66 ).bindparams(description_normalized=unidecode(recipe.description).lower().strip(), id=recipe.id) 

67 ) 

68 

69 ingredients = session.execute(select(RecipeIngredient)).scalars().all() 1a

70 for ingredient in ingredients: 70 ↛ 71line 70 didn't jump to line 71 because the loop on line 70 never started1a

71 if ingredient.note is not None: 

72 session.execute( 

73 sa.text( 

74 f"UPDATE {RecipeIngredient.__tablename__} SET note_normalized=:note_normalized WHERE id=:id" 

75 ).bindparams(note_normalized=unidecode(ingredient.note).lower().strip(), id=ingredient.id) 

76 ) 

77 

78 if ingredient.original_text is not None: 

79 session.execute( 

80 sa.text( 

81 f"UPDATE {RecipeIngredient.__tablename__} SET original_text_normalized=:original_text_normalized WHERE id=:id" 

82 ).bindparams( 

83 original_text_normalized=unidecode(ingredient.original_text).lower().strip(), id=ingredient.id 

84 ) 

85 ) 

86 session.commit() 1a

87 

88 

89def upgrade(): 1a

90 # ### commands auto generated by Alembic - please adjust! ### 

91 

92 # Set column default first, since we do not have values here yet 

93 op.add_column("recipes", sa.Column("name_normalized", sa.String(), nullable=False, server_default="")) 1a

94 op.add_column("recipes", sa.Column("description_normalized", sa.String(), nullable=True)) 1a

95 op.drop_index("ix_recipes_description", table_name="recipes") 1a

96 op.drop_index("ix_recipes_name", table_name="recipes") 1a

97 op.create_index(op.f("ix_recipes_description_normalized"), "recipes", ["description_normalized"], unique=False) 1a

98 op.create_index(op.f("ix_recipes_name_normalized"), "recipes", ["name_normalized"], unique=False) 1a

99 op.add_column("recipes_ingredients", sa.Column("note_normalized", sa.String(), nullable=True)) 1a

100 op.add_column("recipes_ingredients", sa.Column("original_text_normalized", sa.String(), nullable=True)) 1a

101 op.drop_index("ix_recipes_ingredients_note", table_name="recipes_ingredients") 1a

102 op.drop_index("ix_recipes_ingredients_original_text", table_name="recipes_ingredients") 1a

103 op.create_index( 1a

104 op.f("ix_recipes_ingredients_note_normalized"), "recipes_ingredients", ["note_normalized"], unique=False 

105 ) 

106 op.create_index( 1a

107 op.f("ix_recipes_ingredients_original_text_normalized"), 

108 "recipes_ingredients", 

109 ["original_text_normalized"], 

110 unique=False, 

111 ) 

112 do_data_migration() 1a

113 # Remove server default now that column should be filled for all rows 

114 with op.batch_alter_table("recipes", schema=None) as batch_op: 1a

115 batch_op.alter_column("name_normalized", existing_type=sa.String(), server_default=None) 1a

116 # ### end Alembic commands ### 

117 

118 

119def downgrade(): 1a

120 # ### commands auto generated by Alembic - please adjust! ### 

121 op.drop_index(op.f("ix_recipes_ingredients_original_text_normalized"), table_name="recipes_ingredients") 

122 op.drop_index(op.f("ix_recipes_ingredients_note_normalized"), table_name="recipes_ingredients") 

123 op.create_index("ix_recipes_ingredients_original_text", "recipes_ingredients", ["original_text"], unique=False) 

124 op.create_index("ix_recipes_ingredients_note", "recipes_ingredients", ["note"], unique=False) 

125 op.drop_column("recipes_ingredients", "original_text_normalized") 

126 op.drop_column("recipes_ingredients", "note_normalized") 

127 op.drop_index(op.f("ix_recipes_name_normalized"), table_name="recipes") 

128 op.drop_index(op.f("ix_recipes_description_normalized"), table_name="recipes") 

129 op.create_index("ix_recipes_name", "recipes", ["name"], unique=False) 

130 op.create_index("ix_recipes_description", "recipes", ["description"], unique=False) 

131 op.drop_column("recipes", "description_normalized") 

132 op.drop_column("recipes", "name_normalized") 

133 # ### end Alembic commands ###