dy-dashboard/import_overseas_orders.py
2026-10-28 11:14:17 +08:00

171 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""导入海外下单表到数据库"""
import os, sys, re
import openpyxl
import pymysql
from config import DB_CONFIG
EXCEL_PATH = "/home/gxd/.openclaw/workspace-dingtalk-assistant/media/inbound/海外下单表(跟单)6-17-1781682944613.xlsx"
# 58列字段定义
COLUMNS = [
("日期", "DATE"),
("计划下单时间", "DATETIME"),
("产品编码", "VARCHAR(100)"),
("单价", "DECIMAL(12,4)"),
("是否审核价格", "VARCHAR(50)"),
("数量", "INT"),
("金额", "DECIMAL(14,2)"),
("供应商", "VARCHAR(200)"),
("仓库", "VARCHAR(200)"),
("货品名称", "VARCHAR(500)"),
("新旧品", "VARCHAR(50)"),
("是否已做采购单", "VARCHAR(50)"),
("是否做入库", "VARCHAR(50)"),
("采购员", "VARCHAR(500)"),
("下单人", "VARCHAR(100)"),
("进度", "VARCHAR(200)"),
("下单备注", "TEXT"),
("采购开发", "VARCHAR(200)"),
("旺店通生产单号", "VARCHAR(100)"),
("是否已录入到旺店通", "VARCHAR(50)"),
("实际到货日期", "VARCHAR(50)"),
("实际到货数量辅助", "INT"),
("辅助", "VARCHAR(100)"),
("实际到货数量", "INT"),
("预计到货日期", "VARCHAR(50)"),
("未到货数", "INT"),
("状态", "VARCHAR(50)"),
]
# 1-31 到货日明细
for i in range(1, 32):
COLUMNS.append((str(i), "INT"))
CREATE_SQL = """
CREATE TABLE IF NOT EXISTS overseas_orders (
id INT AUTO_INCREMENT PRIMARY KEY,
{fields},
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
"""
def main():
conn = pymysql.connect(**DB_CONFIG)
cur = conn.cursor()
# 1. 建表
field_defs = ", ".join([f"`{name}` {dtype} DEFAULT NULL" for name, dtype in COLUMNS])
sql = CREATE_SQL.format(fields=field_defs)
cur.execute(sql)
print("✅ 表 overseas_orders 已就绪")
# 2. 清空旧数据
cur.execute("TRUNCATE TABLE overseas_orders")
print("✅ 已清空旧数据")
# 3. 读 Excel
wb = openpyxl.load_workbook(EXCEL_PATH, data_only=True)
ws = wb.active
# 验证表头
headers = []
for col in range(1, ws.max_column + 1):
val = ws.cell(row=1, column=col).value
headers.append(str(val).strip() if val else "")
expected = [c[0] for c in COLUMNS]
mismatch = []
for i, (h, e) in enumerate(zip(headers, expected)):
if h != e:
mismatch.append(f" 列{i+1}: 期望'{e}' 实际'{h}'")
if mismatch:
print("⚠️ 表头不匹配:")
for m in mismatch:
print(m)
return
# 4. 导入数据
col_types = [c[1] for c in COLUMNS]
def clean_val(val, dtype):
if val is None:
return None
s = str(val).strip()
if not s:
return None
if dtype.startswith('INT'):
nums = re.sub(r'[^0-9\-]', '', s)
if nums and nums != '-':
try: return int(nums)
except: return None
clean = re.sub(r'[^0-9]', '', s)
if clean:
try: return int(clean)
except: return None
return None
if dtype.startswith('DECIMAL'):
clean = re.sub(r'[^0-9\.\-]', '', s)
if clean and clean != '.':
try: return float(clean)
except: return None
return None
if dtype == 'DATE':
date_match = re.match(r'(\d{4})[\-\/](\d{1,2})[\-\/](\d{1,2})', s)
if date_match:
return f"{date_match.group(1)}-{int(date_match.group(2)):02d}-{int(date_match.group(3)):02d}"
return None if not s else s
if dtype == 'DATETIME':
dt_match = re.match(r'(\d{4})[\-\/](\d{1,2})[\-\/](\d{1,2})\s+(\d{1,2}):(\d{1,2})(:(\d{1,2}))?', s)
if dt_match:
return f"{dt_match.group(1)}-{int(dt_match.group(2)):02d}-{int(dt_match.group(3)):02d} {int(dt_match.group(4)):02d}:{dt_match.group(5)}:00"
return None if not s else s
return s if s else None
placeholders = ", ".join(["%s"] * len(COLUMNS))
col_names = ", ".join([f"`{c[0]}`" for c in COLUMNS])
insert_sql = f"INSERT INTO overseas_orders ({col_names}) VALUES ({placeholders})"
total = 0
batch = []
for row_idx in range(2, ws.max_row + 1):
row_data = []
has_data = False
for col_idx in range(1, len(COLUMNS) + 1):
val = ws.cell(row=row_idx, column=col_idx).value
cleaned = clean_val(val, col_types[col_idx - 1])
row_data.append(cleaned)
if cleaned is not None:
has_data = True
if not has_data:
continue
batch.append(tuple(row_data))
total += 1
if len(batch) >= 500:
cur.executemany(insert_sql, batch)
conn.commit()
print(f" 已导入 {total} 行...")
batch = []
if batch:
cur.executemany(insert_sql, batch)
conn.commit()
print(f"✅ 导入完成,共 {total} 行")
# 5. 验证
cur.execute("SELECT COUNT(*) FROM overseas_orders")
cnt = cur.fetchone()[0]
print(f"📊 数据库记录数: {cnt}")
cur.execute("SELECT `日期`,`产品编码`,`货品名称`,`数量`,`供应商`,`状态` FROM overseas_orders WHERE `日期` IS NOT NULL ORDER BY `日期` DESC LIMIT 5")
print("\n最新记录:")
for r in cur.fetchall():
print(f" {r[0]} | {r[1]} | {r[2][:25]}... | {r[3]}件 | {r[4]} | {r[5]}")
conn.close()
if __name__ == "__main__":
main()