#!/usr/bin/env bash # 美团券头图大小/类型回填 —— 全量重跑一轮 ETL,把 meituan_coupon.image_size / image_type 灌满。 # 上线本 PR 后在服务器手动跑一次,立即回填存量券(不必等定时器逐轮 upsert 自然补齐)。 # # 用法(服务器, root): # cd /opt/shaguabijia-app-server # sudo bash deploy/backfill_image_meta.sh # # 全量一轮 ~70min,建议在 tmux/screen 里跑,防 SSH 断开中断 # # 前提:已拉到含本 PR 的 main、已跑 `alembic upgrade head`(脚本会自检列是否存在)、 # 已 restart shaguabijia-app-server.service。服务器 MT_CPS_PROXY 留空(直连 CDN)。 set -euo pipefail APP_DIR="${APP_DIR:-/opt/shaguabijia-app-server}" PY="$APP_DIR/.venv/bin/python" cd "$APP_DIR" mkdir -p data LOG="data/etl_backfill_$(date +%Y%m%d_%H%M%S).log" # 退出时务必恢复定时器(即使 ETL 中途失败,也不把 timer 留在停用态) restore_timer() { systemctl start meituan-etl.timer 2>/dev/null || true; } trap restore_timer EXIT echo "[0/3] 自检 image_size/image_type 列(缺列说明没迁移,先跑 alembic upgrade head)..." "$PY" -c "from sqlalchemy import inspect; from app.db.session import engine; \ cols=[c['name'] for c in inspect(engine).get_columns('meituan_coupon')]; \ import sys; (('image_size' in cols) and ('image_type' in cols)) or sys.exit(' ❌ 缺列,请先: sudo .venv/bin/python -m alembic upgrade head'); \ print(' ✓ 列已就绪')" echo "[1/3] 停定时器,防与定时轮次并发占锁..." systemctl stop meituan-etl.timer 2>/dev/null || true echo "[2/3] 全量重跑 ETL(~70min;日志 $LOG)..." # 不走 systemctl:meituan-etl.service 有 20min 硬超时,全量一轮跑不完会被掐断。 "$PY" -m scripts.pull_meituan_coupons --once --prune-hours 24 2>&1 | tee "$LOG" echo "[3/3] 验证填充率..." "$PY" - <<'PYEOF' from sqlalchemy import text from app.db.session import engine engine.echo = False with engine.connect() as c: tot = c.execute(text("SELECT count(*) FROM meituan_coupon")).scalar() enr = c.execute(text("SELECT count(*) FROM meituan_coupon WHERE image_size IS NOT NULL")).scalar() gif = c.execute(text("SELECT count(*) FROM meituan_coupon WHERE image_type='image/gif'")).scalar() print(f" 总 {tot} 行 | 有 image_size {enr} ({enr*100//max(tot,1)}%) | GIF {gif} 张") PYEOF echo "✅ 回填完成(定时器已恢复)。"