class UserRole(db.Model): __tablename__ = "user_roles" __table_args__ = (db.UniqueConstraint("user_id", "role_id", name="_user_role_constraint"), ) """Primary Keys""" # Parent user_id = db.Column(db.Integer, db.ForeignKey("users.id"), primary_key=True, nullable=False) # Child role_id = db.Column(db.Integer, db.ForeignKey("roles.id"), primary_key=True, nullable=False) """Relationships""" # Parent user = db.relationship("User", back_populates="user_roles") # Child role = db.relationship("Role", back_populates="users", lazy="joined") def __init__(self, role=None, user=None): self.role = role self.user = user def __repr__(self): return f"<UserRole - {self.user.username} has role {self.role.name}>"
class RecipeCuisine(db.Model): """Association Table for many-to-many relationships for recipes and cuisines""" __tablename__ = "recipe_cuisines" __table_args__ = (db.UniqueConstraint("recipe_id", "cuisine_id", name="_recipe_cuisine_constraint"), ) """Columns""" # Parent recipe_id = db.Column(db.Integer, db.ForeignKey("recipes.id"), primary_key=True, nullable=False) # Child cuisine_id = db.Column(db.Integer, db.ForeignKey("cuisines.id"), primary_key=True, nullable=False) """Relationships""" # Parent recipe = db.relationship("Recipe", back_populates="recipe_cuisines") # Child cuisine = db.relationship("Cuisine", back_populates="recipes", lazy="joined") def __init__(self, cuisine=None, recipe=None): """Called when appending Cuisine objects to Recipe objects, child used as first arg""" self.cuisine = cuisine self.recipe = recipe def __repr__(self): return f"<RecipeCuisine - {self.cuisine.name}/{self.recipe.name}>"
class RecipeDietType(db.Model): __tablename__ = "recipe_diet_types" __table_args__ = (db.UniqueConstraint( "recipe_id", "diet_type_id", name="_recipe_diet_type_constraint"), ) """Primary Keys""" # Parent recipe_id = db.Column(db.Integer, db.ForeignKey("recipes.id"), primary_key=True, nullable=False) # Child diet_type_id = db.Column(db.Integer, db.ForeignKey("diet_types.id"), primary_key=True, nullable=False) """Relationships""" # Parent recipe = db.relationship("Recipe", back_populates="recipe_diet_types") # Child diet_type = db.relationship("DietType", back_populates="recipes", lazy="joined") def __init__(self, diet_type=None, recipe=None): """Called when appending DietType objects to Recipe objects, child used as first arg""" self.diet_type = diet_type self.recipe = recipe def __repr__(self): return f"<RecipeDietType - {self.recipe.name} / {self.diet_type.name}>"
class ShoppingList(db.Model): __tablename__ = "shopping_lists" """Primary Keys""" household_id = db.Column(db.Integer, db.ForeignKey("households.id"), primary_key=True, nullable=False) ingredient_id = db.Column(db.Integer, db.ForeignKey("ingredients.id"), primary_key=True, nullable=False) """Relationships""" ingredient = db.relationship("Ingredient", lazy="joined") household = db.relationship("Household", back_populates="shopping_list_items") """Extra Data""" time_created = db.Column(db.DateTime, default=func.now(), server_default=func.now()) time_updated = db.Column(db.DateTime, onupdate=func.now()) time_removed = db.Column(db.DateTime) still_needed = db.Column(db.Boolean, default=True) def __init__(self, ingredient=None, household=None): self.ingredient = ingredient self.household = household
class RecipeTag(db.Model): __tablename__ = "recipe_tags" __table_args__ = (db.UniqueConstraint("recipe_id", "tag_id", name="_recipe_tag_constraint"), ) """Columns""" recipe_id = db.Column(db.Integer, db.ForeignKey("recipes.id"), primary_key=True, nullable=False) tag_id = db.Column(db.Integer, db.ForeignKey("tags.id"), primary_key=True, nullable=False) """Relationships""" recipe = db.relationship("Recipe", back_populates="tags") tag = db.relationship("Tag", back_populates="recipes") def __repr__(self): return f"<RecipeTag {self.tag.name} on {self.recipe.name}>"
def reference_col( tablename: str, nullable=False, pk_name="id", foreign_key_kwargs=None, column_kwargs=None, ): """Column that adds primary key foreign key reference. Usage: :: category_id = reference_col('category') category = relationship('Category', backref='categories') """ foreign_key_kwargs = foreign_key_kwargs or {} column_kwargs = column_kwargs or {} return Column( db.ForeignKey(f"{tablename}.{pk_name}", **foreign_key_kwargs), nullable=nullable, **column_kwargs, )
class RecipeIngredient(db.Model): """Association object for recipe ingredients""" __tablename__ = "recipe_ingredients" """ This constraint was causing issues on recipe import for recipes that had (for example) "lime" and "lime seasoning". Both were assigned the same Spoonacular ID, which caused db issues while assigning recipe ingredients. Removing for now. """ # __table_args__ = ( # db.UniqueConstraint( # "recipe_id", # "ingredient_id", # "original_string", # name="_recipe_ingredient_uix", # ), # ) """Primary Keys""" id = db.Column(db.Integer, primary_key=True, autoincrement=True) recipe_id = db.Column( db.Integer, db.ForeignKey("recipes.id"), primary_key=False, nullable=False ) ingredient_id = db.Column( db.Integer, db.ForeignKey("ingredients.id"), primary_key=False, nullable=False ) """Original Strings In the Spoonacular response, it grabs the original ingredient string from the recipe, which can contain special formatting. For display purposes, this is stored in this table """ original_string = db.Column(db.String) """Quantities""" amount = db.Column(db.Float) unit = db.Column(db.String) us_amount = db.Column(db.Float) us_unit_short = db.Column(db.String) us_unit_long = db.Column(db.String) metric_amount = db.Column(db.Float) metric_unit_short = db.Column(db.String) metric_unit_long = db.Column(db.String) """Nutrition""" caffeine = db.Column(db.Float, default=0.0) calcium = db.Column(db.Float, default=0.0) calories = db.Column(db.Float, default=0.0) carbohydrates = db.Column(db.Float, default=0.0) cholesterol = db.Column(db.Float, default=0.0) choline = db.Column(db.Float, default=0.0) copper = db.Column(db.Float, default=0.0) fat = db.Column(db.Float, default=0.0) fiber = db.Column(db.Float, default=0.0) folate = db.Column(db.Float, default=0.0) folic_acid = db.Column(db.Float, default=0.0) iron = db.Column(db.Float, default=0.0) magnesium = db.Column(db.Float, default=0.0) manganese = db.Column(db.Float, default=0.0) mono_unsaturated_fat = db.Column(db.Float, default=0.0) net_carbohydrates = db.Column(db.Float, default=0.0) phosphorous = db.Column(db.Float, default=0.0) poly_unsaturated_fat = db.Column(db.Float, default=0.0) potassium = db.Column(db.Float, default=0.0) protein = db.Column(db.Float, default=0.0) saturated_fat = db.Column(db.Float, default=0.0) selenium = db.Column(db.Float, default=0.0) sodium = db.Column(db.Float, default=0.0) sugar = db.Column(db.Float, default=0.0) vitamin_a = db.Column(db.Float, default=0.0) vitamin_b1 = db.Column(db.Float, default=0.0) vitamin_b12 = db.Column(db.Float, default=0.0) vitamin_b2 = db.Column(db.Float, default=0.0) vitamin_b3 = db.Column(db.Float, default=0.0) vitamin_b5 = db.Column(db.Float, default=0.0) vitamin_b6 = db.Column(db.Float, default=0.0) vitamin_c = db.Column(db.Float, default=0.0) vitamin_d = db.Column(db.Float, default=0.0) vitamin_e = db.Column(db.Float, default=0.0) vitamin_k = db.Column(db.Float, default=0.0) zinc = db.Column(db.Float, default=0.0) """Glycemic Information""" glycemic_index = db.Column(db.Float, default=0.0) glycemic_load = db.Column(db.Float, default=0.0) """Cost Information""" estimated_cost_cents = db.Column(db.Float, default=0.0) """Relationships""" recipe = db.relationship("Recipe", back_populates="ingredients") ingredient = db.relationship("Ingredient", back_populates="recipes") def __repr__(self): return f"<RecipeIngredient {self.ingredient.name} in {self.recipe.name}>" def __setitem__(self, key, value): setattr(self, key, value) def __getitem__(self, key): return getattr(self, key)