backfill_inventory_site_tokens.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #!/usr/bin/env python3
  2. """为 site_access_token 为空的出入库单补 token。
  3. Usage:
  4. cd backend && source venv/bin/activate
  5. python scripts/backfill_inventory_site_tokens.py
  6. python scripts/backfill_inventory_site_tokens.py --dry-run
  7. """
  8. from __future__ import annotations
  9. import argparse
  10. import sys
  11. from pathlib import Path
  12. BACKEND_ROOT = Path(__file__).resolve().parents[1]
  13. if str(BACKEND_ROOT) not in sys.path:
  14. sys.path.insert(0, str(BACKEND_ROOT))
  15. from sqlalchemy.orm import Session
  16. from app.core.database import SessionLocal
  17. from app.models.db_models import DbInboundOutbound
  18. from app.services.db_inventory_site_token import ensure_site_access_token
  19. def backfill(*, dry_run: bool = False) -> int:
  20. db: Session = SessionLocal()
  21. updated = 0
  22. try:
  23. rows = (
  24. db.query(DbInboundOutbound)
  25. .filter(
  26. DbInboundOutbound.del_flag == 0,
  27. (DbInboundOutbound.site_access_token.is_(None))
  28. | (DbInboundOutbound.site_access_token == ""),
  29. )
  30. .all()
  31. )
  32. for row in rows:
  33. ensure_site_access_token(row)
  34. updated += 1
  35. if dry_run:
  36. db.rollback()
  37. print(f"[dry-run] would update {updated} inventory rows")
  38. else:
  39. db.commit()
  40. print(f"updated {updated} inventory rows")
  41. return updated
  42. finally:
  43. db.close()
  44. def main() -> None:
  45. parser = argparse.ArgumentParser(description="Backfill db_inbound_outbound site_access_token")
  46. parser.add_argument("--dry-run", action="store_true", help="Preview without committing")
  47. args = parser.parse_args()
  48. backfill(dry_run=args.dry_run)
  49. if __name__ == "__main__":
  50. main()