fix(flask_server): 修复 pickle 反序列化后 JSON 序列化问题
问题修复: - pickle 反序列化后 attrs 包含真实 DataFrame/Series 对象 - build_premium_result_from_attrs 需要兼容 Series 对象和字典格式 - API 层需要将 DataFrame/Series 转换为 JSON 可序列化格式 修复方案: - build_premium_result_from_attrs 支持 pd.Series 和 dict 两种输入 - API 层将 DataFrame 转换为 records 格式(orient='records') - API 层将 Series 索引转换为字符串日期 - 过滤内部缓存元数据(_cache_*)
This commit is contained in:
@@ -460,12 +460,12 @@ def build_premium_result(premium_series: pd.Series) -> Dict:
|
||||
}
|
||||
|
||||
|
||||
def build_premium_result_from_attrs(premium_data: Dict) -> Dict:
|
||||
def build_premium_result_from_attrs(premium_data) -> Dict:
|
||||
"""
|
||||
从 attrs 格式构建溢价率返回结果
|
||||
从 attrs 格式构建溢价率返回结果(兼容 Series 对象和字典格式)
|
||||
|
||||
Args:
|
||||
premium_data: attrs 中的溢价率数据,格式为:
|
||||
premium_data: pd.Series 对象或字典格式:
|
||||
{
|
||||
'type': 'series',
|
||||
'data': {date_str: premium_value, ...},
|
||||
@@ -475,16 +475,25 @@ def build_premium_result_from_attrs(premium_data: Dict) -> Dict:
|
||||
Returns:
|
||||
包含 premium_series, latest_premium, premium_date, premium_stats 的字典
|
||||
"""
|
||||
if not premium_data or premium_data.get('type') != 'series':
|
||||
# 处理 None
|
||||
if premium_data is None:
|
||||
return {}
|
||||
|
||||
# 从 dict 恢复为 Series
|
||||
premium_dict = premium_data.get('data', {})
|
||||
if not premium_dict:
|
||||
# 如果是 pd.Series 对象(pickle 反序列化后)
|
||||
if isinstance(premium_data, pd.Series):
|
||||
premium_series = premium_data
|
||||
# 如果是字典格式(旧 JSON 序列化格式)
|
||||
elif isinstance(premium_data, dict):
|
||||
if premium_data.get('type') != 'series':
|
||||
return {}
|
||||
premium_dict = premium_data.get('data', {})
|
||||
if not premium_dict:
|
||||
return {}
|
||||
premium_series = pd.Series(premium_dict)
|
||||
premium_series.index = pd.to_datetime(premium_series.index)
|
||||
else:
|
||||
return {}
|
||||
|
||||
premium_series = pd.Series(premium_dict)
|
||||
premium_series.index = pd.to_datetime(premium_series.index)
|
||||
premium_series.index.name = 'date'
|
||||
|
||||
# 转换为日期-溢价率列表
|
||||
@@ -735,13 +744,49 @@ def get_ohlcv():
|
||||
|
||||
# 提取净值到顶层(方便调用方使用)
|
||||
if 'nav' in attrs:
|
||||
result['nav'] = attrs['nav']
|
||||
nav_df = attrs['nav']
|
||||
if isinstance(nav_df, pd.DataFrame):
|
||||
# 将 DataFrame 转换为列表格式(JSON 可序列化)
|
||||
nav_df_copy = nav_df.reset_index().copy()
|
||||
nav_df_copy['date'] = nav_df_copy['date'].dt.strftime('%Y-%m-%d')
|
||||
nav_dict = {
|
||||
'data': nav_df_copy.to_dict(orient='records'),
|
||||
'count': len(nav_df_copy)
|
||||
}
|
||||
result['nav'] = nav_dict
|
||||
else:
|
||||
result['nav'] = nav_df
|
||||
|
||||
# 提取溢价率到顶层(调用业务函数处理格式)
|
||||
if 'premium' in attrs:
|
||||
premium_result = build_premium_result_from_attrs(attrs['premium'])
|
||||
if premium_result:
|
||||
result.update(premium_result)
|
||||
|
||||
# 将 attrs 中的 DataFrame/Series 转换为字典格式(用于 JSON 序列化)
|
||||
attrs_serializable = {}
|
||||
for key, value in attrs.items():
|
||||
if isinstance(value, pd.DataFrame):
|
||||
df_copy = value.reset_index().copy()
|
||||
if 'date' in df_copy.columns:
|
||||
df_copy['date'] = df_copy['date'].dt.strftime('%Y-%m-%d')
|
||||
attrs_serializable[key] = {
|
||||
'data': df_copy.to_dict(orient='records'),
|
||||
'count': len(df_copy)
|
||||
}
|
||||
elif isinstance(value, pd.Series):
|
||||
# 将 Series 索引转换为字符串
|
||||
series_copy = value.copy()
|
||||
series_copy.index = series_copy.index.strftime('%Y-%m-%d')
|
||||
attrs_serializable[key] = {
|
||||
'type': 'series',
|
||||
'data': series_copy.to_dict(),
|
||||
'name': value.name
|
||||
}
|
||||
else:
|
||||
attrs_serializable[key] = value
|
||||
|
||||
result['attrs'] = attrs_serializable
|
||||
|
||||
# 如果用户指定了类型但与自动检测不同,显示提示
|
||||
if asset_type_param and detected_type != final_type:
|
||||
|
||||
Reference in New Issue
Block a user