pandas读取mysql数据 重试3次后将退出,确保更高程度上可以拿到数据库数据
当服务器资源不够的情况下会造成程序执行一次失败,可以等待资源释放再次取获取,但也不要一直获取,不然会导致服务器压力增大
def read_to_database(query_sql, db_engine, remark=None):
"""读取数据库数据"""
MAX_ATTEMPTS = 3
ATTEMPTS = 0
df_data = pd.DataFrame()
while ATTEMPTS < MAX_ATTEMPTS:
try:
df_data = pd.read_sql(query_sql, db_engine)
if not df_data.empty:
logger.info(f"{remark}=====数据读取成功")
break
except Exception as e:
ATTEMPTS += 1
logger.error(f"{remark}=====数据读取失败: {e}")
logger.info(f"{remark}=====正在进行第 {ATTEMPTS} 次重试...")
# 等待5秒后进行重试
time.sleep(5)
else:
ATTEMPTS += 1
if df_data.empty:
logger.error(f"{remark}=====达到最大重试次数,无法读取数据库中的数据!")
return df_data
往写入数据库写入数据是也可能会遇到数据库过载,需要等会重试
def write_to_database(df, table_name, engine, remark=None):
"""往写入数据库"""
MAX_ATTEMPTS = 3
ATTEMPTS = 0
while ATTEMPTS < MAX_ATTEMPTS:
try:
df.to_sql(table_name, engine, if_exists='append', index=False)
logger.info(f"{remark}=====数据写入成功")
return True
except Exception as e:
ATTEMPTS += 1
logger.error(f"{remark}=====数据写入失败: {e}")
logger.info(f"{remark}=====正在进行第 {ATTEMPTS} 次重试...")
# 等待5秒后进行重试
time.sleep(5)
logger.error(f"{remark}=====达到最大重试次数,无法写入数据到数据库中!")
return False
通过工厂模式与数据库建立连接池
因为同时要与多个数据库建立连接, 减少重复建立连接导致资源消耗过大
class SQLAlchemyEngineFactory:
"""工厂模式"""
_engines = {}
def create_engine_func(self, host, user, pwd, db_name):
config = f'mysql+pymysql://{user}:{pwd}@{host}:3306/{db_name}'
# 针对具体需求可以设置对应的连接池大小
if db_name == "form_data" or db_name == "dwd_tp":
# form_data 独有连接池大小
pool_size = 100
max_overflow = 50
else:
pool_size = 30
max_overflow = 30
if config not in self._engines:
# pool_size 和 max_overflow表示连接池的大小,当所有的连接都在使用时,还可以创建50个额外的连接。
# pool_timeout 表示当所有的连接都在使用,并且已经有50个额外的连接在使用时,新的数据库操作会等待600秒,
# 如果在这个时间内仍然没有可用的连接,那么将会抛出一个异常
self._engines[config] = create_engine(
config,
poolclass=QueuePool,
pool_size=pool_size,
max_overflow=max_overflow,
pool_timeout=120
)
return self._engines[config]