137 lines
4.5 KiB
Python
137 lines
4.5 KiB
Python
#!/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-1781683171953.xlsx"
|
||
|
||
COLUMNS = [
|
||
("日期", "DATE"),
|
||
("编码", "VARCHAR(100)"),
|
||
("名称", "VARCHAR(500)"),
|
||
("单价", "DECIMAL(12,4)"),
|
||
("数量", "INT"),
|
||
("合计", "DECIMAL(14,2)"),
|
||
("供应商", "VARCHAR(200)"),
|
||
("仓库到货", "VARCHAR(200)"),
|
||
("进度", "TEXT"),
|
||
("是否已做采购单", "VARCHAR(50)"),
|
||
("是否已做入库", "VARCHAR(50)"),
|
||
("采购下单人", "VARCHAR(100)"),
|
||
("旺店通编号", "VARCHAR(100)"),
|
||
("是否已录入旺店通", "VARCHAR(50)"),
|
||
("到货日期", "VARCHAR(50)"),
|
||
("状态", "VARCHAR(50)"),
|
||
("做货天数", "VARCHAR(50)"),
|
||
("包材开发", "VARCHAR(200)"),
|
||
]
|
||
|
||
CREATE_SQL = """
|
||
CREATE TABLE IF NOT EXISTS packaging_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()
|
||
|
||
field_defs = ", ".join([f"`{name}` {dtype} DEFAULT NULL" for name, dtype in COLUMNS])
|
||
cur.execute(CREATE_SQL.format(fields=field_defs))
|
||
print("✅ 表 packaging_orders 已就绪")
|
||
|
||
cur.execute("TRUNCATE TABLE packaging_orders")
|
||
print("✅ 已清空旧数据")
|
||
|
||
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
|
||
|
||
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
|
||
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
|
||
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 packaging_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} 行")
|
||
|
||
cur.execute("SELECT COUNT(*) FROM packaging_orders")
|
||
print(f"📊 数据库记录数: {cur.fetchone()[0]}")
|
||
|
||
cur.execute("SELECT `日期`,`编码`,`名称`,`数量`,`供应商`,`状态` FROM packaging_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()
|