134 lines
5.9 KiB
Python
134 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
"""导入 2026-06-11 库存数据"""
|
|
import sys, os, csv, json, subprocess, pymysql
|
|
from datetime import datetime
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location("config", "config.py")
|
|
config = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(config)
|
|
DB_CONFIG = config.DB_CONFIG
|
|
|
|
TMP_DIR = "tmp_csv"
|
|
os.makedirs(TMP_DIR, exist_ok=True)
|
|
|
|
def parse_int(val):
|
|
if val is None or val == '' or str(val).upper() == 'NA': return 0
|
|
try: return int(float(val))
|
|
except: return 0
|
|
|
|
def parse_float(val):
|
|
if val is None or val == '' or str(val).upper() == 'NA': return 0.0
|
|
try: return float(val)
|
|
except: return 0.0
|
|
|
|
def parse_datetime(val):
|
|
if not val or val == '' or str(val).upper() == 'NA': return None
|
|
try: return datetime.strptime(val.strip(), '%Y-%m-%d %H:%M:%S')
|
|
except:
|
|
try: return datetime.strptime(val.strip(), '%Y-%m-%d')
|
|
except: return None
|
|
|
|
FILES = [
|
|
("20260611-wdt-kcmx-01", "2026-06-11", "01", "yQod3RxJKG0y54ygF467yORxJkb4Mw9r"),
|
|
("20260611-wdt-kcmx-02", "2026-06-11", "02", "l6Pm2Db8D4znYAnxt9kvqaOD8xLq0Ee4"),
|
|
("20260611-wdt-kcmx-03", "2026-06-11", "03", "pYLaezmVNe3rBDrNCGE94M5mWrMqPxX6"),
|
|
("20260611-wdt-kcmx-04", "2026-06-11", "04", "9bN7RYPWdM970O7GtkM4ogZnVZd1wyK0"),
|
|
("20260611-wdt-kcmx-05", "2026-06-11", "05", "OG9lyrgJPzx5KM5ACz0kBwyPWzN67Mw4"),
|
|
("20260611-wdt-kcmx-06", "2026-06-11", "06", "X6GRezwJlApOwMOZtrKOnyql8dqbropQ"),
|
|
("20260611-wdt-kcmx-07", "2026-06-11", "07", "l6Pm2Db8D4znYAnxt9kvndyo8xLq0Ee4"),
|
|
("20260611-wdt-kcmx-08", "2026-06-11", "08", "OG9lyrgJPzx5KM5ACz0k9l26WzN67Mw4"),
|
|
("20260611-wdt-kcmx-09", "2026-06-11", "09", "1DKw2zgV2PdeDAe0HPa0LaaD8B5r9YAn"),
|
|
("20260611-wdt-kcmx-10", "2026-06-11", "10", "b9Y4gmKWrPnBK2BwHjbgavQxJGXn6lpz"),
|
|
("20260611-wdt-kcmx-11", "2026-06-11", "11", "vNG4YZ7JnPzwqNwLH90wZ9XKW2LD0oRE"),
|
|
("20260611-wdt-kcmx-12", "2026-06-11", "12", "4lgGw3P8vRrBDmBeUpb9de4R85daZ90D"),
|
|
("20260611-wdt-kcmx-13", "2026-06-11", "13", "X6GRezwJlApOwMOZtrKOnYlb8dqbropQ"),
|
|
("20260611-wdt-kcmx-15", "2026-06-11", "15", "ndMj49yWjXkyODyehwveX5P1J3pmz5aA"),
|
|
("20260611-wdt-kcmx-16", "2026-06-11", "16", "4lgGw3P8vRrBDmBeUpb9GA7985daZ90D"),
|
|
("20260611-wdt-kcmx-20", "2026-06-11", "20", "dxXB52LJqnmBErB3tM7LnGeb8qjMp697"),
|
|
("20260611-wdt-kcmx-22", "2026-06-11", "22", "0eMKjyp813eL9ALkC45vdYgvVxAZB1Gv"),
|
|
("20260611-wdt-kcmx-23", "2026-06-11", "23", "QBnd5ExVEvZ73d7xC251k3gkJyeZqMmz"),
|
|
("20260611-wdt-kcmx-24", "2026-06-11", "24", "l6Pm2Db8D4znYAnxt9kvqGAX8xLq0Ee4"),
|
|
]
|
|
|
|
total_imported = 0
|
|
success = 0
|
|
|
|
for i, (name, data_date, wh_code, node_id) in enumerate(FILES, 1):
|
|
print(f"\n[{i}/{len(FILES)}] {name} (仓库:{wh_code})")
|
|
|
|
# 下载
|
|
result = subprocess.run(
|
|
["dws", "doc", "download", "--node", node_id, "--output", "/dev/stdout", "--format", "json"],
|
|
capture_output=True, text=True, timeout=30
|
|
)
|
|
try:
|
|
url = json.loads(result.stdout).get('resourceUrl')
|
|
if not url:
|
|
print(f" ❌ 无法获取下载链接"); continue
|
|
except:
|
|
print(f" ❌ 解析下载响应失败"); continue
|
|
|
|
local_path = os.path.join(TMP_DIR, f"{name}.csv")
|
|
subprocess.run(["curl", "-sL", url, "-o", local_path], capture_output=True, timeout=30)
|
|
|
|
if not os.path.exists(local_path) or os.path.getsize(local_path) < 50:
|
|
print(f" ❌ 下载失败或文件过小"); continue
|
|
|
|
# 编码处理
|
|
r = subprocess.run(["file", local_path], capture_output=True, text=True, timeout=5)
|
|
if 'ISO' in r.stdout or '8859' in r.stdout:
|
|
utf8_path = local_path.replace('.csv', '_utf8.csv')
|
|
subprocess.run(["iconv", "-f", "GBK", "-t", "UTF-8", local_path, "-o", utf8_path], capture_output=True, timeout=10)
|
|
os.replace(utf8_path, local_path)
|
|
|
|
# 导入
|
|
conn = pymysql.connect(**DB_CONFIG, cursorclass=pymysql.cursors.DictCursor)
|
|
inserted = 0
|
|
try:
|
|
with open(local_path, 'r', encoding='utf-8-sig') as f:
|
|
reader = csv.DictReader(f)
|
|
rows = list(reader)
|
|
|
|
with conn.cursor() as cur:
|
|
for row in rows:
|
|
try:
|
|
cur.execute("""
|
|
INSERT INTO inventory_detail
|
|
(data_date, source, warehouse_code, goods_code, product_code, product_name,
|
|
brand, cost_price, available_qty, production_in_transit, purchase_in_transit,
|
|
category1, category2, category3, created_time)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
""", (
|
|
data_date, 'wdt', wh_code,
|
|
row.get('商家编码', '').strip(),
|
|
row.get('货品编号', '').strip(),
|
|
row.get('货品名称', '').strip(),
|
|
row.get('品牌', '').strip(),
|
|
parse_float(row.get('成本价', 0)),
|
|
parse_int(row.get('可用库存', 0)),
|
|
parse_int(row.get('生产在途量', 0)),
|
|
parse_int(row.get('采购在途', 0)),
|
|
row.get('一级类目', '').strip(),
|
|
row.get('二级类目', '').strip(),
|
|
row.get('三级类目', '').strip(),
|
|
parse_datetime(row.get('单品创建时间', ''))
|
|
))
|
|
inserted += 1
|
|
except Exception as e:
|
|
pass
|
|
conn.commit()
|
|
print(f" ✅ 导入 {inserted} 条")
|
|
total_imported += inserted
|
|
success += 1
|
|
except Exception as e:
|
|
conn.rollback()
|
|
print(f" ❌ 导入异常: {e}")
|
|
finally:
|
|
conn.close()
|
|
|
|
print(f"\n{'='*50}")
|
|
print(f"库存导入完成! 成功: {success}/{len(FILES)} 个文件, {total_imported} 条记录")
|
|
print(f"{'='*50}")
|