"""Atomic import of reviewed route bindings, direct BOM inputs and safe outputs.""" import sys,json,csv,collections from pathlib import Path from decimal import Decimal P=Path(__file__).parent sys.path.insert(0,str(P.parent/'iqc-import-20261012/deps')) import pymysql plan=json.loads((P/'binding-plan.json').read_text(encoding='utf8')) snapshot=json.loads((P/'before-binding-snapshot.json').read_text(encoding='utf8')) def dump(n,v):(P/n).write_text(json.dumps(v,ensure_ascii=False,indent=2,default=str),encoding='utf8') def normalized(rows):return json.loads(json.dumps(rows,default=str)) def flag(value):return int.from_bytes(value,'big') if isinstance(value,bytes) else int(value or 0) c=pymysql.connect(host='36.213.150.237',port=10000,user='root',password=sys.stdin.readline().strip(),database='mom-hm',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor,connect_timeout=10,read_timeout=60) log=[];newroutes=[];updatedsteps=0 try: with c.cursor() as q: q.execute('SELECT DATABASE() db');assert q.fetchone()['db']=='mom-hm' q.execute("SELECT GET_LOCK('stp-routes-20261012',10) ok");assert q.fetchone()['ok']==1 c.begin();before={} tables=['mes_md_item','mes_md_product_bom','mes_pro_route','mes_pro_route_process','mes_pro_route_product','mes_pro_route_product_bom'] for t in tables: q.execute('SELECT ENGINE FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=%s',(t,));assert q.fetchone()['ENGINE']=='InnoDB' q.execute('SELECT * FROM '+t+' WHERE deleted=0 ORDER BY id FOR UPDATE');before[t]=list(q.fetchall()) if normalized(before[t])!=sorted(snapshot[t],key=lambda x:x['id']): dump('changed-'+t+'.json',before[t]) raise AssertionError(f'{t} changed; re-review required') dump('before-binding-import.json',before) def execute(sql,args):log.append(q.mogrify(sql,args)+';');q.execute(sql,args) def insert(t,v): cols=list(v);sql='INSERT INTO '+t+' (`'+'`,`'.join(cols)+"`,creator,updater) VALUES ("+','.join(['%s']*len(cols))+",'1','1')" execute(sql,tuple(v[k] for k in cols));return q.lastrowid rt={} for r in plan['routes']: if r['id'] is None: assert not any(x['code']==r['code'] for x in before['mes_pro_route']) r['id']=insert('mes_pro_route',{'code':r['code'],'name':r['name'],'description':r.get('description','来源:'+r['document_code']+';按产品小包装规格细分产出;非倒冲、手动领料。'),'status':1,'remark':'产品名称、规格及BOM匹配;投入保留原BOM比例;原料BOM/参数未补齐前保持停用。'}) newroutes.append(r['id']);isnew=True else:isnew=False rt[r['route_key']]=r['id'] for idx,st in enumerate(r['steps']): v=dict(route_id=r['id'],process_id=st['process_id'],sort=st['sort'],next_process_id=r['steps'][idx+1]['process_id'] if idx+1