Coverage for opt/mealie/lib/python3.12/site-packages/mealie/alembic/versions/2025-02-09-15.31.00_7cf3054cbbcc_remove_instructions_index.py: 77%

84 statements  

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

1"""remove instructions index 

2 

3Revision ID: 7cf3054cbbcc 

4Revises: b9e516e2d3b3 

5Create Date: 2025-02-09 15:31:00.772295 

6 

7""" 

8 

9import sqlalchemy as sa 1a

10from sqlalchemy import orm 1a

11from alembic import op 1a

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

13from mealie.core.root_logger import get_logger 1a

14 

15# revision identifiers, used by Alembic. 

16revision = "7cf3054cbbcc" 1a

17down_revision: str | None = "b9e516e2d3b3" 1a

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

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

20 

21logger = get_logger() 1a

22 

23 

24class SqlAlchemyBase(orm.DeclarativeBase): 1a

25 @classmethod 1a

26 def normalized_fields(cls) -> list[orm.InstrumentedAttribute]: 1a

27 return [] 

28 

29 

30class RecipeModel(SqlAlchemyBase): 1a

31 __tablename__ = "recipes" 1a

32 

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

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

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

36 

37 @classmethod 1a

38 def normalized_fields(cls): 1a

39 return [cls.name_normalized, cls.description_normalized] 

40 

41 

42class RecipeIngredientModel(SqlAlchemyBase): 1a

43 __tablename__ = "recipes_ingredients" 1a

44 

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

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

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

48 

49 @classmethod 1a

50 def normalized_fields(cls): 1a

51 return [cls.note_normalized, cls.original_text_normalized] 

52 

53 

54class IngredientFoodModel(SqlAlchemyBase): 1a

55 __tablename__ = "ingredient_foods" 1a

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

57 name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

58 plural_name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

59 

60 @classmethod 1a

61 def normalized_fields(cls): 1a

62 return [cls.name_normalized, cls.plural_name_normalized] 

63 

64 

65class IngredientFoodAliasModel(SqlAlchemyBase): 1a

66 __tablename__ = "ingredient_foods_aliases" 1a

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

68 name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

69 

70 @classmethod 1a

71 def normalized_fields(cls): 1a

72 return [cls.name_normalized] 

73 

74 

75class IngredientUnitModel(SqlAlchemyBase): 1a

76 __tablename__ = "ingredient_units" 1a

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

78 name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

79 plural_name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

80 abbreviation_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

81 plural_abbreviation_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

82 

83 @classmethod 1a

84 def normalized_fields(cls): 1a

85 return [ 

86 cls.name_normalized, 

87 cls.plural_name_normalized, 

88 cls.abbreviation_normalized, 

89 cls.plural_abbreviation_normalized, 

90 ] 

91 

92 

93class IngredientUnitAliasModel(SqlAlchemyBase): 1a

94 __tablename__ = "ingredient_units_aliases" 1a

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

96 name_normalized: orm.Mapped[str | None] = orm.mapped_column(sa.String, index=True) 1a

97 

98 @classmethod 1a

99 def normalized_fields(cls): 1a

100 return [cls.name_normalized] 

101 

102 

103def truncate_normalized_fields() -> None: 1a

104 bind = op.get_bind() 1a

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

106 

107 models: list[type[SqlAlchemyBase]] = [ 1a

108 RecipeModel, 

109 RecipeIngredientModel, 

110 IngredientFoodModel, 

111 IngredientFoodAliasModel, 

112 IngredientUnitModel, 

113 IngredientUnitAliasModel, 

114 ] 

115 

116 for model in models: 1a

117 for record in session.query(model).all(): 117 ↛ 118line 117 didn't jump to line 118 because the loop on line 117 never started1a

118 for field in model.normalized_fields(): 

119 if not (field_value := getattr(record, field.key)): 

120 continue 

121 

122 setattr(record, field.key, field_value[:255]) 

123 

124 try: 1a

125 session.commit() 1a

126 except Exception: 

127 logger.exception(f"Failed to truncate normalized fields for {model.__name__}") 

128 session.rollback() 

129 

130 

131def upgrade(): 1a

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

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

134 batch_op.drop_index("ix_recipe_instructions_text") 1a

135 

136 # ### end Alembic commands ### 

137 

138 truncate_normalized_fields() 1a

139 

140 

141def downgrade(): 1a

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

143 with op.batch_alter_table("recipe_instructions", schema=None) as batch_op: 

144 batch_op.create_index("ix_recipe_instructions_text", ["text"], unique=False) 

145 

146 # ### end Alembic commands ###