feat: 回填历史报工归属明细

This commit is contained in:
souplearn 2026-07-25 05:53:23 +08:00
parent 7aded6b480
commit 666c26bb57

View File

@ -2,12 +2,16 @@ from pathlib import Path
import re import re
import sys import sys
from sqlalchemy import text from sqlalchemy import select, text
from sqlalchemy.orm import selectinload
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from app.database import engine # noqa: E402 from app.database import SessionLocal, engine # noqa: E402
from app.models import ProductionReport, WorkSession # noqa: E402
from app.services.report_allocations import refresh_report_allocations # noqa: E402
from app.services.work_schedule import get_work_schedule_config # noqa: E402
TABLE_NAME = "production_report_allocations" TABLE_NAME = "production_report_allocations"
@ -374,12 +378,45 @@ def verify_schema(conn) -> None:
raise RuntimeError(f"{TABLE_NAME} missing foreign keys: {', '.join(missing_foreign_keys)}") raise RuntimeError(f"{TABLE_NAME} missing foreign keys: {', '.join(missing_foreign_keys)}")
def _backfill() -> tuple[int, int]:
processed = 0
skipped = 0
query = (
select(ProductionReport)
.options(
selectinload(ProductionReport.items),
selectinload(ProductionReport.session).selectinload(WorkSession.devices),
)
.order_by(ProductionReport.id.asc())
)
with SessionLocal() as db:
reports = db.scalars(query).all()
for report in reports:
if report is None:
skipped += 1
continue
schedule = get_work_schedule_config(db, report.attendance_point_name)
refresh_report_allocations(db, report, schedule=schedule, commit=False)
processed += 1
if processed % 200 == 0:
db.commit()
db.commit()
return processed, skipped
def main() -> None: def main() -> None:
with engine.begin() as conn: with engine.begin() as conn:
ensure_schema(conn) ensure_schema(conn)
verify_schema(conn) verify_schema(conn)
print("report allocations schema migrated") processed, skipped = _backfill()
print(f"report allocations migrated, processed={processed}, skipped={skipped}")
if __name__ == "__main__": if __name__ == "__main__":