重置项目
This commit is contained in:
@@ -38,6 +38,9 @@ _table_cache: dict[str, dict | None] = {
|
||||
"index_daily": None,
|
||||
"index_enriched": None,
|
||||
"index_instruments": None,
|
||||
"etf_daily": None,
|
||||
"etf_enriched": None,
|
||||
"etf_instruments": None,
|
||||
"minute": None,
|
||||
"adj_factor": None,
|
||||
"instruments": None,
|
||||
@@ -262,6 +265,85 @@ def _safe_aggregate_index_instruments(repo) -> dict | None:
|
||||
}
|
||||
|
||||
|
||||
def _safe_aggregate_etf_instruments(repo) -> dict | None:
|
||||
"""ETF instruments 统计 — 优先独立 instruments_etf,兼容旧 instruments_index。"""
|
||||
queries = [
|
||||
"""SELECT count(*) AS rows,
|
||||
count(DISTINCT symbol) AS symbols,
|
||||
count_if(name IS NOT NULL AND name != '') AS named
|
||||
FROM instruments_etf""",
|
||||
"""SELECT count(*) AS rows,
|
||||
count(DISTINCT symbol) AS symbols,
|
||||
count_if(name IS NOT NULL AND name != '') AS named
|
||||
FROM instruments_index
|
||||
WHERE asset_type = 'etf'""",
|
||||
]
|
||||
for sql in queries:
|
||||
try:
|
||||
row = repo.execute_one(sql)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.debug("aggregate etf instruments fallback failed: %s", e)
|
||||
continue
|
||||
if row and row[0]:
|
||||
return {
|
||||
"rows": int(row[0]),
|
||||
"symbols_covered": int(row[1] or 0),
|
||||
"latest_as_of": None,
|
||||
"named": int(row[2] or 0),
|
||||
}
|
||||
return None
|
||||
|
||||
|
||||
def _safe_aggregate_etf_enriched(repo) -> dict | None:
|
||||
"""ETF enriched 统计 — 独立 kline_etf_enriched。"""
|
||||
fields = 0
|
||||
try:
|
||||
cols = repo.execute_all("DESCRIBE kline_etf_enriched")
|
||||
fields = len(cols)
|
||||
except Exception: # noqa: BLE001
|
||||
pass
|
||||
stats = _safe_aggregate(repo, "kline_etf_enriched")
|
||||
if not stats:
|
||||
return None
|
||||
return {**stats, "fields": fields}
|
||||
|
||||
|
||||
def _safe_aggregate_etf_daily(repo) -> dict | None:
|
||||
"""ETF 日K统计 — 优先独立 kline_etf_daily,兼容旧 index 存储。"""
|
||||
queries = [
|
||||
"""SELECT count(*) AS rows,
|
||||
min(date) AS earliest,
|
||||
max(date) AS latest,
|
||||
count(DISTINCT symbol) AS symbols,
|
||||
count(DISTINCT date) AS trading_days
|
||||
FROM kline_etf_daily""",
|
||||
"""SELECT count(*) AS rows,
|
||||
min(date) AS earliest,
|
||||
max(date) AS latest,
|
||||
count(DISTINCT symbol) AS symbols,
|
||||
count(DISTINCT date) AS trading_days
|
||||
FROM kline_index_daily
|
||||
WHERE symbol IN (
|
||||
SELECT DISTINCT symbol FROM instruments_index WHERE asset_type = 'etf'
|
||||
)""",
|
||||
]
|
||||
for sql in queries:
|
||||
try:
|
||||
row = repo.execute_one(sql)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.debug("aggregate etf daily fallback failed: %s", e)
|
||||
continue
|
||||
if row and row[0]:
|
||||
return {
|
||||
"rows": int(row[0]),
|
||||
"earliest_date": str(row[1]) if row[1] else None,
|
||||
"latest_date": str(row[2]) if row[2] else None,
|
||||
"symbols_covered": int(row[3] or 0),
|
||||
"trading_days": int(row[4] or 0),
|
||||
}
|
||||
return None
|
||||
|
||||
|
||||
def _safe_aggregate_adj_factor(repo) -> dict | None:
|
||||
"""adj_factor 视图统计,日期范围对齐日 K 覆盖区间。"""
|
||||
try:
|
||||
@@ -405,6 +487,10 @@ def _compute_storage(data_dir: Path) -> dict:
|
||||
"index_daily": data_dir / "kline_index_daily",
|
||||
"index_enriched": data_dir / "kline_index_enriched",
|
||||
"index_instruments": data_dir / "instruments_index",
|
||||
"etf_daily": data_dir / "kline_etf_daily",
|
||||
"etf_enriched": data_dir / "kline_etf_enriched",
|
||||
"etf_instruments": data_dir / "instruments_etf",
|
||||
"etf_adj_factor": data_dir / "adj_factor_etf",
|
||||
"minute": data_dir / "kline_minute",
|
||||
"adj_factor": data_dir / "adj_factor",
|
||||
"instruments": data_dir / "instruments",
|
||||
@@ -507,10 +593,13 @@ def status(request: Request) -> dict:
|
||||
return {
|
||||
"daily": _get_table_stats("daily", lambda: _safe_aggregate_daily(repo)),
|
||||
"enriched": _get_table_stats("enriched", lambda: _safe_aggregate_enriched(repo)),
|
||||
"index_daily": _get_table_stats("index_daily", lambda: _safe_aggregate_index_daily(repo)),
|
||||
"index_enriched": _get_table_stats("index_enriched", lambda: _safe_aggregate_index_enriched(repo)),
|
||||
"index_instruments": _get_table_stats("index_instruments", lambda: _safe_aggregate_index_instruments(repo)),
|
||||
"minute": _get_table_stats("minute", lambda: _safe_aggregate_minute(repo)),
|
||||
"index_daily": _get_table_stats("index_daily", lambda: _safe_aggregate_index_daily(repo)),
|
||||
"index_enriched": _get_table_stats("index_enriched", lambda: _safe_aggregate_index_enriched(repo)),
|
||||
"index_instruments": _get_table_stats("index_instruments", lambda: _safe_aggregate_index_instruments(repo)),
|
||||
"etf_daily": _get_table_stats("etf_daily", lambda: _safe_aggregate_etf_daily(repo)),
|
||||
"etf_enriched": _get_table_stats("etf_enriched", lambda: _safe_aggregate_etf_enriched(repo)),
|
||||
"etf_instruments": _get_table_stats("etf_instruments", lambda: _safe_aggregate_etf_instruments(repo)),
|
||||
"minute": _get_table_stats("minute", lambda: _safe_aggregate_minute(repo)),
|
||||
"adj_factor": _get_table_stats("adj_factor", lambda: _safe_aggregate_adj_factor(repo)),
|
||||
"instruments": _get_table_stats("instruments", lambda: _safe_aggregate_instruments(repo)),
|
||||
"financials": _get_table_stats("financials", lambda: _safe_aggregate_financials(repo)),
|
||||
@@ -537,8 +626,9 @@ def clear_data(request: Request):
|
||||
deleted = 0
|
||||
|
||||
for sub in (
|
||||
"kline_daily", "kline_daily_enriched", "kline_index_daily", "kline_index_enriched", "kline_minute",
|
||||
"adj_factor", "instruments", "instruments_index", "pools", "financials",
|
||||
"kline_daily", "kline_daily_enriched", "kline_index_daily", "kline_index_enriched",
|
||||
"kline_etf_daily", "kline_etf_enriched", "kline_etf_minute", "kline_minute",
|
||||
"adj_factor", "adj_factor_etf", "instruments", "instruments_index", "instruments_etf", "pools", "financials",
|
||||
"backtest_results", "screener_results", "ai_cache",
|
||||
):
|
||||
d = data_dir / sub
|
||||
@@ -596,10 +686,15 @@ def clear_data(request: Request):
|
||||
"kline_enriched": f"{d}/kline_daily_enriched/**/*.parquet",
|
||||
"kline_index_daily": f"{d}/kline_index_daily/**/*.parquet",
|
||||
"kline_index_enriched": f"{d}/kline_index_enriched/**/*.parquet",
|
||||
"kline_etf_daily": f"{d}/kline_etf_daily/**/*.parquet",
|
||||
"kline_etf_enriched": f"{d}/kline_etf_enriched/**/*.parquet",
|
||||
"kline_etf_minute": f"{d}/kline_etf_minute/**/*.parquet",
|
||||
"kline_minute": f"{d}/kline_minute/**/*.parquet",
|
||||
"adj_factor": f"{d}/adj_factor/**/*.parquet",
|
||||
"adj_factor_etf": f"{d}/adj_factor_etf/**/*.parquet",
|
||||
"instruments": f"{d}/instruments/**/*.parquet",
|
||||
"instruments_index": f"{d}/instruments_index/**/*.parquet",
|
||||
"instruments_etf": f"{d}/instruments_etf/**/*.parquet",
|
||||
}.items():
|
||||
try:
|
||||
repo.db.execute(
|
||||
@@ -638,6 +733,17 @@ _TABLE_FIELD_DESC: dict[str, dict[str, str]] = {
|
||||
"amount": "成交额",
|
||||
},
|
||||
"kline_index_enriched": ENRICHED_COLUMNS,
|
||||
"kline_etf_daily": {
|
||||
"symbol": "ETF代码",
|
||||
"date": "交易日期",
|
||||
"open": "开盘价",
|
||||
"high": "最高价",
|
||||
"low": "最低价",
|
||||
"close": "收盘价",
|
||||
"volume": "成交量",
|
||||
"amount": "成交额",
|
||||
},
|
||||
"kline_etf_enriched": ENRICHED_COLUMNS,
|
||||
"kline_minute": {
|
||||
"symbol": "股票代码",
|
||||
"datetime": "分钟时间戳",
|
||||
@@ -675,6 +781,13 @@ _TABLE_FIELD_DESC: dict[str, dict[str, str]] = {
|
||||
"code": "指数编码(纯数字)",
|
||||
"asset_type": "资产类型(index)",
|
||||
},
|
||||
"instruments_etf": {
|
||||
"symbol": "ETF代码",
|
||||
"name": "ETF名称",
|
||||
"code": "ETF编码(纯数字)",
|
||||
"asset_type": "资产类型(etf)",
|
||||
"source": "数据源",
|
||||
},
|
||||
}
|
||||
|
||||
# view 名 → DuckDB 视图名
|
||||
@@ -684,6 +797,9 @@ _SCHEMA_VIEWS: dict[str, str] = {
|
||||
"index_daily": "kline_index_daily",
|
||||
"index_enriched": "kline_index_enriched",
|
||||
"index_instruments": "instruments_index",
|
||||
"etf_daily": "kline_etf_daily",
|
||||
"etf_enriched": "kline_etf_enriched",
|
||||
"etf_instruments": "instruments_etf",
|
||||
"minute": "kline_minute",
|
||||
"adj_factor": "adj_factor",
|
||||
"instruments": "instruments",
|
||||
@@ -730,7 +846,7 @@ def get_version(request: Request) -> dict:
|
||||
"""
|
||||
from app import __version__
|
||||
|
||||
# 1. 优先用 app.__version__ (开发期 bump_version.py 写入)
|
||||
# 1. 优先用 app.__version__ (唯一权威版本, 打包期由 PyInstaller 注入)
|
||||
if __version__:
|
||||
v = __version__.strip()
|
||||
return {"version": v if v.startswith("v") else f"v{v}"}
|
||||
|
||||
Reference in New Issue
Block a user