Files
mileage-bonus/backfill_july_all_gps.py

102 lines
3.6 KiB
Python

from ast import parse, walk, Call, Constant, keyword
from collections import defaultdict
from datetime import datetime, date
from pathlib import Path
import re
import shutil
import openpyxl
import pymysql
OUTPUT = Path('/Users/kkfluous/Downloads/7月核算结果/7月考核车辆多源里程汇总.xlsx')
BACKUP = Path('/Users/kkfluous/Downloads/7月核算结果/7月考核车辆多源里程汇总_GPS全量回补前.xlsx')
def norm(value):
return re.sub(r'\s+', '', str(value or '')).upper()
def db_config():
tree = parse(Path('/Users/kkfluous/Downloads/replace_gps_jun.py').read_text())
for node in walk(tree):
if not isinstance(node, Call) or getattr(node.func, 'attr', None) != 'connect':
continue
values = {}
for item in node.keywords:
if isinstance(item, keyword) and isinstance(item.value, Constant):
values[item.arg] = item.value.value
if {'host', 'user', 'password', 'database'} <= values.keys():
return values
raise RuntimeError('未找到既有GPS数据库配置')
wb = openpyxl.load_workbook(OUTPUT)
ws = wb.active
header_row = next(r for r in range(1, 8) if ws.cell(r, 12).value == 'GPS里程(km)')
data_start = header_row + 1
plates = sorted({norm(ws.cell(r, 2).value) for r in range(data_start, ws.max_row + 1) if ws.cell(r, 2).value})
cfg = db_config()
cfg.update(charset='utf8mb4', connect_timeout=8, read_timeout=30, write_timeout=30)
conn = pymysql.connect(**cfg)
try:
with conn.cursor() as cur:
placeholders = ','.join(['%s'] * len(plates))
cur.execute(
f'''SELECT plate_number, dates, total_mileage
FROM ln_vehicle_g7_mileage
WHERE dates >= %s AND dates <= %s
AND plate_number IN ({placeholders})''',
[date(2026, 7, 1), date(2026, 7, 31), *plates],
)
db_rows = cur.fetchall()
finally:
conn.close()
daily = defaultdict(dict)
for plate, day, raw_mileage in db_rows:
if isinstance(day, datetime):
day = day.date()
daily[norm(plate)][day] = float(raw_mileage or 0) / 100000.0
if not BACKUP.exists():
shutil.copy2(OUTPUT, BACKUP)
filled = []
still_missing = []
for row in range(data_start, ws.max_row + 1):
cell = ws.cell(row, 12)
if cell.value != '无来源':
continue
plate = norm(ws.cell(row, 2).value)
start = ws.cell(row, 4).value
end = ws.cell(row, 5).value
if isinstance(start, datetime):
start = start.date()
if isinstance(end, datetime):
end = end.date()
matched = [value for day, value in daily.get(plate, {}).items() if start <= day <= end]
if matched:
cell.value = round(sum(matched), 2)
cell.number_format = '#,##0.0'
filled.append((plate, start, end, cell.value))
else:
still_missing.append((plate, start, end))
ws['A1'] = (
'1. 纯氢里程(km)、纯电里程(km)来源于广州平台统计,TBOX里程来源于车机上报的仪表盘里程统计,'
'GPS里程优先使用两份7月GPS日明细,缺失车辆由GPS数据库每日里程按考核区间回补;测试车辆以7月最终考核源表已确认GPS为准\n'
'2. 广州平台总里程(km)=纯氢里程(km)+纯电里程(km)\n'
'3. 已确认广州平台暂未接入86辆普货车数据;所有GPS来源均无对应记录时标记为“无来源”'
)
wb.save(OUTPUT)
print({
'database_rows': len(db_rows),
'database_plates': len(daily),
'backfilled_records': len(filled),
'remaining_missing_records': len(still_missing),
'remaining_missing_plates': len({x[0] for x in still_missing}),
})