def get_df_iter(date_start, date_end, step, df_len_limit=3000, deep=0): """ 获取日期范围内的数据,当数据记录大于上限条数时,将日期范围进行二分法拆分,迭代进行查询 :param date_start: :param date_end: :param step: :param df_len_limit: :param deep: :return: """ for num, (date_from, date_to) in enumerate(iter_2_range(range_date( date_start, date_end, step), has_left_outer=False, has_right_outer=False), start=1): q = query(finance.STK_INCOME_STATEMENT).filter( finance.STK_INCOME_STATEMENT.pub_date > date_2_str(date_from), finance.STK_INCOME_STATEMENT.pub_date <= date_2_str(date_to)) df = finance.run_query(q) df_len = df.shape[0] if df_len >= df_len_limit: if step >= 2: logger.warning('%s%d) [%s ~ %s] 包含 %d 条数据,可能已经超越 %d 条提取上限,开始进一步分割日期', ' ' * deep, num, date_from, date_to, df_len, df_len_limit) yield from get_df_iter(date_from, date_to, step // 2, deep=deep + 1) else: logger.warning('%s%d) [%s ~ %s] 包含 %d 条数据,可能已经超越 %d 条提取上限且无法再次分割日期范围,手动需要补充提取剩余数据', ' ' * deep, num, date_from, date_to, df_len, df_len_limit) yield df, date_from, date_to else: logger.debug('%s%d) [%s ~ %s] 包含 %d 条数据', ' ' * deep, num, date_from, date_to, df_len) yield df, date_from, date_to
def save(self): self.logger.info("更新 %s 开始", self.table_name) has_table = engine_md.has_table(self.table_name) # 判断表是否已经存在 if has_table: with with_db_session(engine_md) as session: sql_str = f"""select trade_date from jq_trade_date where trade_date>(select max(day) from {self.table_name}) order by trade_date""" table = session.execute(sql_str, params={"trade_date": self.BASE_DATE}) trade_date_list = [_[0] for _ in table.fetchall()] date_start = execute_scalar(sql_str, engine_md) self.logger.info('查询 %s 数据使用起始日期 %s', self.table_name, date_2_str(date_start)) else: with with_db_session(engine_md) as session: sql_str = "select trade_date from jq_trade_date where trade_date>=:trade_date order by trade_date" table = session.execute(sql_str, params={"trade_date": self.BASE_DATE}) trade_date_list = [_[0] for _ in table.fetchall()] self.logger.warning('%s 不存在,使用基础日期 %s', self.table_name, self.BASE_DATE) # 查询最新的 trade_date_list.sort() data_count_tot, for_count = 0, len(trade_date_list) try: for num, trade_date in enumerate(trade_date_list): q = query(self.statement) df = get_fundamentals(q, date=date_2_str(trade_date)) if df is None or df.shape[0] == 0: continue logger.debug('%d/%d) %s 包含 %d 条数据', num, for_count, trade_date, df.shape[0]) data_count = bunch_insert_on_duplicate_update( df, self.table_name, engine_md, dtype=self.dtype, myisam_if_create_table=True, primary_keys=['id'], schema=config.DB_SCHEMA_MD) data_count_tot += data_count except: logger.exception("更新 %s 异常", self.table_name) finally: # 导入数据库 logging.info("更新 %s 结束 %d 条信息被更新", self.table_name, data_count_tot)
def get_df_iter(self, date_start, date_end, step, df_len_limit=10000, deep=0): """ 获取日期范围内的数据,当数据记录大于上限条数时,将日期范围进行二分法拆分,迭代进行查询 :param date_start: :param date_end: :param step: :param df_len_limit: :param deep: :return: """ for num, (date_from, date_to) in enumerate(iter_2_range( range_date(date_start, date_end, step), has_left_outer=False, has_right_outer=False), start=1): q = query(self.statement) df = get_fundamentals(q, date=date_2_str(date_to)) df_len = df.shape[0] if df_len >= df_len_limit: if step >= 2: self.logger.warning( '%s%s%d) [%s ~ %s] 包含 %d 条数据,可能已经超越 %d 条提取上限,开始进一步分割日期', self.table_name, ' ' * deep, num, date_from, date_to, df_len, df_len_limit) yield from self.get_df_iter(date_from, date_to, step // 2, deep=deep + 1) else: self.logger.warning( '%s%s%d) [%s ~ %s] 包含 %d 条数据,可能已经超越 %d 条提取上限且无法再次分割日期范围,手动需要补充提取剩余数据', self.table_name, ' ' * deep, num, date_from, date_to, df_len, df_len_limit) yield df, date_from, date_to else: self.logger.debug('%s %s%d) [%s ~ %s] 包含 %d 条数据', self.table_name, ' ' * deep, num, date_from, date_to, df_len) yield df, date_from, date_to