fixing db tables and onplace upgrde

This commit is contained in:
2025-10-02 04:58:42 -07:00
parent 7cbc2d83bb
commit ed5839e222
4 changed files with 122 additions and 21 deletions

View File

@@ -0,0 +1,76 @@
"""Data migration to convert serving_size to float
Revision ID: 13939361fc35
Revises: a11a3921f528
Create Date: 2025-10-01 23:44:34.144506
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '13939361fc35'
down_revision: Union[str, None] = 'a11a3921f528'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""
Data migration to convert existing string-based 'serving_size' values to floats.
This version uses a session to iterate through the data, providing more robust error handling.
"""
bind = op.get_bind()
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=bind)
session = Session()
# Define a simple table structure for our purpose
food_table = sa.Table('foods', sa.MetaData(),
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String),
sa.Column('serving_size', sa.String) # Treat it as String to be safe
)
try:
foods_to_update = session.query(food_table).all()
updated_count = 0
for food in foods_to_update:
# Check if serving_size is a string and needs conversion
if isinstance(food.serving_size, str):
try:
new_size = float(food.serving_size)
# Use session.execute for the update
session.execute(
food_table.update().
where(food_table.c.id == food.id).
values(serving_size=new_size)
)
updated_count += 1
except (ValueError, TypeError):
print(f"Could not convert serving_size for Food ID {food.id} (Name: {food.name}). Value: '{food.serving_size}'")
if updated_count > 0:
session.commit()
print(f"Successfully converted {updated_count} food items.")
else:
print("No food items required an update.")
except Exception as e:
print(f"An error occurred during the data migration: {e}")
session.rollback()
finally:
session.close()
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
# A downgrade for this data migration is not practical as it would require
# converting floats back to strings, which could lead to loss of precision.
# It is better to back up the database before upgrading.
pass
# ### end Alembic commands ###

View File

@@ -0,0 +1,38 @@
"""Ensure serving_size column is Float
Revision ID: d0c142fbf0b0
Revises: 13939361fc35
Create Date: 2025-10-02 00:27:05.400224
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'd0c142fbf0b0'
down_revision: Union[str, None] = '13939361fc35'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('foods', schema=None) as batch_op:
batch_op.alter_column('serving_size',
existing_type=sa.VARCHAR(),
type_=sa.Float(),
existing_nullable=True)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('foods', schema=None) as batch_op:
batch_op.alter_column('serving_size',
existing_type=sa.Float(),
type_=sa.VARCHAR(),
existing_nullable=True)
# ### end Alembic commands ###

View File

@@ -14,23 +14,11 @@ router = APIRouter()
# Meals tab
@router.get("/meals", response_class=HTMLResponse)
async def meals_page(request: Request, db: Session = Depends(get_db)):
try:
from sqlalchemy.orm import joinedload
logging.info("DEBUG: Starting meals query with eager loading")
meals = db.query(Meal).options(joinedload(Meal.meal_foods).joinedload(MealFood.food)).all()
logging.info(f"DEBUG: Retrieved {len(meals)} meals")
foods = db.query(Food).all()
logging.info(f"DEBUG: Retrieved {len(foods)} foods")
# Test template rendering with a simple test
logging.info("DEBUG: Testing template rendering...")
test_data = {"request": request, "meals": meals, "foods": foods}
return templates.TemplateResponse("meals.html", test_data)
except Exception as e:
logging.error(f"DEBUG: Error in meals_page: {str(e)}", exc_info=True)
# Return a simple error response for debugging
return HTMLResponse(f"<h1>Error in meals page</h1><pre>{str(e)}</pre><pre>{type(e).__name__}</pre>")
from sqlalchemy.orm import joinedload
meals = db.query(Meal).options(joinedload(Meal.meal_foods).joinedload(MealFood.food)).all()
foods = db.query(Food).all()
return templates.TemplateResponse("meals.html",
{"request": request, "meals": meals, "foods": foods})
@router.post("/meals/upload")
async def bulk_upload_meals(file: UploadFile = File(...), db: Session = Depends(get_db)):

View File

@@ -253,12 +253,11 @@ def run_migrations():
if has_foods and (not has_alembic_version or not alembic_version_has_content):
logging.info("DEBUG: Existing database detected. Stamping with initial migration.")
command.stamp(alembic_cfg, "head")
# Stamp with the specific initial migration that creates all tables
command.stamp(alembic_cfg, "cf94fca21104")
logging.info("DEBUG: Database stamped successfully.")
else:
logging.info("DEBUG: No stamping needed or fresh database.")
# Now, run upgrades
# Now, run upgrades to bring the database to the latest version
logging.info("DEBUG: Running alembic upgrade...")
command.upgrade(alembic_cfg, "head")
logging.info("DEBUG: Database migrations run successfully.")