fix: hk_rate.py SSOT归一——知微版(DB优先读fx_rate表)同步到权威版+三处硬链接(卫生审计diverged_copy)
This commit is contained in:
@@ -18,6 +18,44 @@ from datetime import date
|
||||
CACHE_PATH = os.path.expanduser("~/.cache/hk_exchange_rate.json")
|
||||
CACHE_TTL = 86400 # 24小时,合理配置常量
|
||||
|
||||
# 数据库路径 - 使用绝对路径
|
||||
DB_PATH = "/home/hmo/MoFin/data/mofin.db"
|
||||
|
||||
def _get_rate_from_db():
|
||||
"""从 fx_rate 表获取汇率"""
|
||||
try:
|
||||
import sqlite3
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.execute(
|
||||
"SELECT rate FROM fx_rate WHERE currency_pair='HKD_CNY' AND is_active=1 ORDER BY created_at DESC LIMIT 1"
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
conn.close()
|
||||
if row and 0.7 < row[0] < 1.0:
|
||||
return round(float(row[0]), 6)
|
||||
except Exception as e:
|
||||
print(f"[hk_rate] 数据库读取失败: {e}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
def _set_rate_in_db(rate, source='api_refresh'):
|
||||
"""将汇率写入 fx_rate 表"""
|
||||
try:
|
||||
import sqlite3
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
# 先将旧的设为 inactive
|
||||
conn.execute("UPDATE fx_rate SET is_active=0 WHERE currency_pair='HKD_CNY'")
|
||||
# 插入新汇率
|
||||
conn.execute(
|
||||
"INSERT INTO fx_rate (currency_pair, rate, source, created_at, is_active) VALUES (?, ?, ?, datetime('now','localtime'), 1)",
|
||||
('HKD_CNY', rate, source)
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[hk_rate] 数据库写入失败: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
# 不再硬编码备用值,每次取缓存中的最近一次有效汇率
|
||||
def _load_last_rate():
|
||||
"""从缓存文件读取上次已知有效汇率"""
|
||||
@@ -70,12 +108,18 @@ def _fetch_rate():
|
||||
|
||||
|
||||
def hkd_to_cny(force_refresh=False):
|
||||
"""获取 HKD→CNY 汇率,缓存过期则自动刷新"""
|
||||
"""获取 HKD→CNY 汇率,优先使用数据库中的权威汇率"""
|
||||
os.makedirs(os.path.dirname(CACHE_PATH), exist_ok=True)
|
||||
now = time.time()
|
||||
rate = None
|
||||
|
||||
# 读缓存
|
||||
# 1. 优先从数据库获取(权威源)
|
||||
if not force_refresh:
|
||||
rate = _get_rate_from_db()
|
||||
if rate is not None:
|
||||
return rate
|
||||
|
||||
# 2. 读本地缓存
|
||||
if not force_refresh:
|
||||
try:
|
||||
with open(CACHE_PATH) as f:
|
||||
@@ -87,11 +131,13 @@ def hkd_to_cny(force_refresh=False):
|
||||
if (cache_date == date.today().isoformat()
|
||||
and rate is not None
|
||||
and (now - cached_at) < CACHE_TTL):
|
||||
# 写入数据库作为权威源
|
||||
_set_rate_in_db(rate, 'cache_sync')
|
||||
return rate
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 刷新
|
||||
# 3. 刷新API
|
||||
rate = _fetch_rate()
|
||||
if rate is None:
|
||||
# API全挂,用缓存中的上次有效汇率
|
||||
@@ -100,7 +146,7 @@ def hkd_to_cny(force_refresh=False):
|
||||
rate = 0.87 # 极限兜底,纯预防
|
||||
print(f"[hk_rate] API不可达,使用 {rate} (fallback)", file=sys.stderr)
|
||||
else:
|
||||
# 写缓存
|
||||
# 写本地缓存
|
||||
try:
|
||||
with open(CACHE_PATH, "w") as f:
|
||||
json.dump({
|
||||
@@ -111,6 +157,8 @@ def hkd_to_cny(force_refresh=False):
|
||||
}, f)
|
||||
except Exception:
|
||||
pass
|
||||
# 写入数据库作为权威源
|
||||
_set_rate_in_db(rate, 'api_refresh')
|
||||
|
||||
return rate
|
||||
|
||||
@@ -121,4 +169,4 @@ def refresh_rate():
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = hkd_to_cny()
|
||||
print(f"HKD/CNY = {r}")
|
||||
print(f"HKD/CNY = {r}")
|
||||
Reference in New Issue
Block a user