fix(audit): candidates UPSERT保计算列+market_scanner INSERT对齐表结构+拆除sync_decisions_to_db地雷
举一反三审计结果: - accumulation_scanner: INSERT OR REPLACE整行替换,promoted=1的候选被重置score/promoted/log → ON CONFLICT DO UPDATE只更新扫描器自有列(cron活跃,今日必修) - market_scanner: INSERT引用表中不存在的列(price/score/entry_low等),实测必失败 → 对齐真实schema+同款UPSERT(孤儿脚本顺手修) - sync_decisions_to_db.py: 全表DELETE再从已不存在的decisions.json重建,地雷→归档
This commit is contained in:
@@ -228,10 +228,15 @@ def main():
|
||||
if exists:
|
||||
continue
|
||||
|
||||
# UPSERT:只更新扫描器自有列,保留 score_*/pass_*/promoted/log/zhiwei_* 等计算列
|
||||
# (原 INSERT OR REPLACE 会把 promoted=1 的行整行替换,计算列全部清零——2026-07-23 审计发现)
|
||||
conn.execute(
|
||||
"INSERT OR REPLACE INTO candidates (code, name, sector, reason, "
|
||||
"INSERT INTO candidates (code, name, sector, reason, "
|
||||
"entry_range, stop_loss, target, created_at) "
|
||||
"VALUES (?,?,?,?,?,?,?,datetime('now','localtime'))",
|
||||
"VALUES (?,?,?,?,?,?,?,datetime('now','localtime')) "
|
||||
"ON CONFLICT(code) DO UPDATE SET "
|
||||
"name=excluded.name, sector=excluded.sector, reason=excluded.reason, "
|
||||
"entry_range=excluded.entry_range, stop_loss=excluded.stop_loss, target=excluded.target",
|
||||
(code, name, "accumulation",
|
||||
f"主力建仓特征({reasons}) 评分{score}/7",
|
||||
f"{entry_low}~{entry_high}", sl, tp)
|
||||
|
||||
@@ -159,17 +159,22 @@ def scan_candidates():
|
||||
new_candidates.append(candidate)
|
||||
print(f" ✅ {code} {name} 价{price} (+{chg:.1f}%) 评分{score}", flush=True)
|
||||
|
||||
# 4. 写入candidates表
|
||||
# 4. 写入candidates表(对齐真实表结构:表无 price/change_pct/score/entry_low/entry_high/
|
||||
# take_profit/source 列,原 INSERT 必失败——2026-07-23 审计实测确认。
|
||||
# UPSERT 只更新扫描器自有列,保留 score_*/pass_*/promoted/log 等计算列)
|
||||
if new_candidates:
|
||||
conn = get_conn()
|
||||
for c in new_candidates:
|
||||
conn.execute(
|
||||
"INSERT OR REPLACE INTO candidates (code, name, price, change_pct, score, "
|
||||
"entry_low, entry_high, stop_loss, take_profit, source, sector, reason, created_at) "
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,datetime('now','localtime'))",
|
||||
(c["code"], c["name"], c["price"], c["change_pct"], c["score"],
|
||||
c["entry_low"], c["entry_high"], c["stop_loss"], c["take_profit"],
|
||||
c["source"], c["sector"], c["reason"])
|
||||
"INSERT INTO candidates (code, name, sector, reason, "
|
||||
"entry_range, stop_loss, target, created_at) "
|
||||
"VALUES (?,?,?,?,?,?,?,datetime('now','localtime')) "
|
||||
"ON CONFLICT(code) DO UPDATE SET "
|
||||
"name=excluded.name, sector=excluded.sector, reason=excluded.reason, "
|
||||
"entry_range=excluded.entry_range, stop_loss=excluded.stop_loss, target=excluded.target",
|
||||
(c["code"], c["name"], c.get("sector") or c.get("source", "market_scanner"),
|
||||
f"{c['reason']} 价{c['price']}(+{c['change_pct']:.1f}%) 评分{c['score']}",
|
||||
f"{c['entry_low']}~{c['entry_high']}", c["stop_loss"], c["take_profit"])
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user