ZhuLinsen/daily_stock_analysis · error · DataFetchError
Baostock 获取数据失败: {e}
Error message
Baostock 获取数据失败: {e} What it means
The generic DataFetchError catch-all at the bottom of BaostockFetcher's query block: any exception during login-context query execution that is not already a DataFetchError (those are re-raised verbatim) gets wrapped with the original cause chained. It covers row iteration, DataFrame construction, and any unexpected baostock SDK exception.
Source
Thrown at data_provider/baostock_fetcher.py:253
if rs.error_code != '0':
raise DataFetchError(f"Baostock 查询失败: {rs.error_msg}")
# 转换为 DataFrame
data_list = []
while rs.next():
data_list.append(rs.get_row_data())
if not data_list:
raise DataFetchError(f"Baostock 未查询到 {stock_code} 的数据")
df = pd.DataFrame(data_list, columns=rs.fields)
return df
except Exception as e:
if isinstance(e, DataFetchError):
raise
raise DataFetchError(f"Baostock 获取数据失败: {e}") from e
def _normalize_data(self, df: pd.DataFrame, stock_code: str) -> pd.DataFrame:
"""
标准化 Baostock 数据
Baostock 返回的列名:
date, open, high, low, close, volume, amount, pctChg
需要映射到标准列名:
date, open, high, low, close, volume, amount, pct_chg
"""
df = df.copy()
# 列名映射(只需要处理 pctChg)
column_mapping = {
'pctChg': 'pct_chg',
}
View on GitHub (pinned to 5159bd72e8)
Solutions
- Inspect e.__cause__ for the real exception type — that determines fix direction (SDK version, network, or data shape).
- For socket drops, retry once inside a fresh _baostock_session (a new login resets the connection).
- Pin the baostock version if rs.fields/row API changed.
- Let the manager fall back to Akshare for this code if baostock keeps failing.
Example fix
# before
try:
df = baostock_fetcher.fetch(code, start, end)
except DataFetchError:
raise # no diagnostics, batch dies
# after
try:
df = baostock_fetcher.fetch(code, start, end)
except DataFetchError as e:
logger.error('baostock failed for %s: %s (cause=%r)', code, e, e.__cause__)
df = akshare_fetcher.fetch(code, start, end) # fallback Defensive patterns
Strategy: fallback
Validate before calling
import baostock as bs rs = bs.query_history_k_data_plus(code='sh.600519', fields='date,open,high,low,close,volume,amount,pctChg', start_date='2025-01-01', end_date='2025-01-10', frequency='d', adjustflag='2') assert rs.fields, 'baostock result API mismatch — pin the SDK version'
Try / catch
try:
df = baostock_fetcher.fetch(code, start, end)
except DataFetchError as e:
logger.warning('baostock failed for %s: %s (cause=%r)', code, e, e.__cause__)
df = akshare_fetcher.fetch(code, start, end) Prevention
- Pin the baostock package version; its result-set API (fields/next/get_row_data) drifts between releases.
- Log __cause__ to separate SDK-shape errors from network drops.
- Use a fresh _baostock_session per retry so a broken connection is re-established.
When it happens
Trigger: Exceptions while consuming the baostock result: rs.next()/get_row_data() throwing on a dropped socket, pd.DataFrame construction failing on mismatched rs.fields after a baostock version change, or attribute errors from a partially-initialized baostock module. Explicit DataFetchErrors (137/138) bypass this wrapper via the isinstance re-raise.
Common situations: baostock package updated with a changed result API breaking the row loop; connection dying mid-iteration under load; monkeypatched/mocked baostock in tests missing attributes.
Related errors
- Akshare 获取 ETF 数据失败: {e}
- Akshare 获取美股数据失败: {e}
- Akshare 获取港股数据失败: {e}
- Baostock 登录失败: {login_result.error_msg}
- Baostock 查询失败: {rs.error_msg}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/9e5bc37c4d49f41a.
Report an issue: GitHub.