From cf605ac5b824fe314d642090474a7a64975db9f9 Mon Sep 17 00:00:00 2001 From: Qihang Zhang Date: Sun, 20 Apr 2025 17:13:06 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(data=5Fmanager):=20=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E6=96=B0=E9=97=BB=E8=8E=B7=E5=8F=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E6=8C=87=E5=AE=9A=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E6=9F=A5=E8=AF=A2=E5=92=8C=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=A3=80=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_manager.py | 82 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/data_manager.py b/data_manager.py index 72feb26..78fa4e8 100644 --- a/data_manager.py +++ b/data_manager.py @@ -201,50 +201,52 @@ class DataFetcher: DataFetcher.get_news() @staticmethod - def get_news(src='sina', fields=None): + def get_news(src='sina', fields=None, start_date=None, end_date=None): """ - 智能获取新闻数据,只获取数据库中不存在的部分 - + 智能获取新闻数据,可获取指定时间范围内的数据 参数: src (str): 新闻来源,如'sina'、'wallstreetcn'等 fields (str): 需要获取的字段,默认为'datetime,title,channels,content' - + start_date (str): 可选的开始日期,格式'YYYY-MM-DD HH:MM:SS' + end_date (str): 可选的结束日期,格式'YYYY-MM-DD HH:MM:SS',默认为当前时间 返回: bool: 是否成功获取数据 """ table_name = 'news' - # 固定的历史起始点 - HISTORY_START = '2025-04-15 00:00:00' + HISTORY_START = '2025-04-01 00:00:00' # 如果未指定字段,设置默认字段 if fields is None: fields = 'datetime,title,channels,content' - # 获取当前时间作为结束时间 - end_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + # 确定结束时间 + if end_date is None: + end_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - # 检查表是否存在,确定起始时间 - if not db_manager.table_exists(table_name): - logger.info(f"表 {table_name} 不存在,将获取从 {HISTORY_START} 至今的所有新闻数据") - # 从固定起始点获取所有数据 + # 确定开始时间 + if start_date: + logger.info(f"使用用户指定的开始日期: {start_date}") + # 如果未指定开始日期,使用智能逻辑确定 + elif not db_manager.table_exists(table_name): + logger.info(f"表 {table_name} 不存在,将获取从 {HISTORY_START} 至 {end_date} 的新闻数据") start_date = HISTORY_START else: - # 表存在,查询最新的新闻时间 + # 表存在,查询符合条件的最新的新闻时间 try: - newest_query = f"SELECT MAX(datetime) as max_time FROM {table_name}" + # 查询小于等于end_date的最新新闻时间 + newest_query = f"SELECT MAX(datetime) as max_time FROM {table_name} WHERE datetime <= '{end_date}'" newest_result = db_manager.query(newest_query) - # 如果有数据并且值不为None if not newest_result.empty and newest_result['max_time'].iloc[0] is not None: newest_time = newest_result['max_time'].iloc[0] - logger.info(f"数据库中最新的新闻时间为: {newest_time}") - + logger.info(f"数据库中小于等于 {end_date} 的最新新闻时间为: {newest_time}") # 从最新时间开始获取新数据 start_date = newest_time else: - # 数据库表存在但没有数据 - logger.info(f"数据库表 {table_name} 存在但没有数据,将获取从 {HISTORY_START} 至今的所有新闻数据") + # 数据库表存在但没有符合条件的数据 + logger.info( + f"数据库表 {table_name} 存在但没有小于等于 {end_date} 的数据,将获取从 {HISTORY_START} 至 {end_date} 的新闻数据") start_date = HISTORY_START except Exception as e: logger.error(f"查询最新新闻时间时出错: {e}") @@ -252,6 +254,14 @@ class DataFetcher: # 出错时,从固定起始点获取 start_date = HISTORY_START + # 检查时间范围有效性 + start_datetime = datetime.strptime(start_date, '%Y-%m-%d %H:%M:%S') + end_datetime = datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S') + + if start_datetime >= end_datetime: + logger.info(f"开始时间 {start_date} 不早于结束时间 {end_date},无需获取数据") + return True + logger.info(f"开始获取 {start_date} 至 {end_date} 的新闻数据") return DataFetcher._fetch_news_recursive(src, start_date, end_date, fields, table_name) @@ -403,7 +413,7 @@ class DataReader: return [] @staticmethod - def get_table_data_by_date(table_name, start_date=None, end_date=None, filter_main_board=True): + def get_table_data_by_date(table_name, start_date=None, end_date=None, filter_main_board=False): """ 从数据库获取指定表的数据,并截取指定日期范围内的数据 @@ -411,7 +421,7 @@ class DataReader: table_name (str): 数据库表名 start_date (str): 开始日期,格式'YYYYMMDD',默认为30天前 end_date (str): 结束日期,格式'YYYYMMDD',默认为今天 - filter_main_board (bool): 是否只返回主板上市股票的数据,默认为True + filter_main_board (bool): 是否只返回主板上市股票的数据,默认为False error_prefix (str): 错误日志的前缀 返回: @@ -453,3 +463,33 @@ class DataReader: logger.error(f"获取{table_name}数据时出错: {e}") logger.debug(f"完整的错误追踪信息:\n{traceback.format_exc()}") return pd.DataFrame() + + @staticmethod + def get_news(start_date=None, end_date=None, update=False): + # 先检查表是否存在 + if not db_manager.table_exists('news') or update: + logger.debug(f"表 trade_cal 不存在") + # 自动拉取交易日历 + try: + DataFetcher.get_news() + except Exception as e: + logger.error(f"自动拉去news时出错: {e}") + logger.debug(f"完整的错误追踪信息:\n{traceback.format_exc()}") + return [] + + # 设置默认日期范围 + if start_date is None: + start_date = '2025-04-15 00:00:00' + if end_date is None: + end_date = datetime.now().strftime('YYYY-MM-DD HH:MM:SS') + + + try: + # 查询数据 + df = db_manager.load_df_from_db('news', conditions=f"datetime BETWEEN '{start_date}' AND '{end_date}'") + return df + + except Exception as e: + logger.error(f"获取news数据时出错: {e}") + logger.debug(f"完整的错误追踪信息:\n{traceback.format_exc()}") + return pd.DataFrame()