|
@@ -44,36 +44,75 @@ class MySQLConnectionPool:
|
|
|
user=sql_user,
|
|
user=sql_user,
|
|
|
password=sql_password,
|
|
password=sql_password,
|
|
|
database=sql_db,
|
|
database=sql_db,
|
|
|
- charset="utf8mb4",
|
|
|
|
|
- use_unicode=True,
|
|
|
|
|
- init_command="SET NAMES utf8mb4",
|
|
|
|
|
- ping=1, # 0:完全关闭(更快), 1:仅在取连接时检查, 2:每次执行前检查连接有效性,防止使用已断开的连接
|
|
|
|
|
|
|
+ ping=2, # 每次执行前检查连接有效性,防止使用已断开的连接
|
|
|
connect_timeout=5, # 连接超时时间(秒)
|
|
connect_timeout=5, # 连接超时时间(秒)
|
|
|
# read_timeout=30, # 读取超时时间(秒)
|
|
# read_timeout=30, # 读取超时时间(秒)
|
|
|
write_timeout=30 # 写入超时时间(秒)
|
|
write_timeout=30 # 写入超时时间(秒)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ # def _execute(self, query, args=None, commit=False):
|
|
|
|
|
+ # """
|
|
|
|
|
+ # 执行SQL
|
|
|
|
|
+ # :param query: SQL语句
|
|
|
|
|
+ # :param args: SQL参数
|
|
|
|
|
+ # :param commit: 是否提交事务
|
|
|
|
|
+ # :return: 查询结果
|
|
|
|
|
+ # """
|
|
|
|
|
+ # try:
|
|
|
|
|
+ # with self.pool.connection() as conn:
|
|
|
|
|
+ # with conn.cursor() as cursor:
|
|
|
|
|
+ # cursor.execute(query, args)
|
|
|
|
|
+ # if commit:
|
|
|
|
|
+ # conn.commit()
|
|
|
|
|
+ # self.log.debug(f"sql _execute, Query: {query}, Rows: {cursor.rowcount}")
|
|
|
|
|
+ # return cursor
|
|
|
|
|
+ # except Exception as e:
|
|
|
|
|
+ # if commit and conn:
|
|
|
|
|
+ # conn.rollback()
|
|
|
|
|
+ # self.log.exception(f"Error executing query: {e}, Query: {query}, Args: {args}")
|
|
|
|
|
+ # raise e
|
|
|
|
|
+
|
|
|
def _execute(self, query, args=None, commit=False):
|
|
def _execute(self, query, args=None, commit=False):
|
|
|
"""
|
|
"""
|
|
|
- 执行SQL
|
|
|
|
|
|
|
+ 执行SQL(带断连重试)
|
|
|
:param query: SQL语句
|
|
:param query: SQL语句
|
|
|
:param args: SQL参数
|
|
:param args: SQL参数
|
|
|
:param commit: 是否提交事务
|
|
:param commit: 是否提交事务
|
|
|
:return: 查询结果
|
|
:return: 查询结果
|
|
|
"""
|
|
"""
|
|
|
- try:
|
|
|
|
|
- with self.pool.connection() as conn:
|
|
|
|
|
- with conn.cursor() as cursor:
|
|
|
|
|
- cursor.execute(query, args)
|
|
|
|
|
- if commit:
|
|
|
|
|
- conn.commit()
|
|
|
|
|
- self.log.debug(f"sql _execute, Query: {query}, Rows: {cursor.rowcount}")
|
|
|
|
|
- return cursor
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
- if commit and conn:
|
|
|
|
|
- conn.rollback()
|
|
|
|
|
- self.log.exception(f"Error executing query: {e}, Query: {query}, Args: {args}")
|
|
|
|
|
- raise e
|
|
|
|
|
|
|
+ conn = None
|
|
|
|
|
+ for attempt in range(2): # 最多重试1次
|
|
|
|
|
+ try:
|
|
|
|
|
+ with self.pool.connection() as conn:
|
|
|
|
|
+ with conn.cursor() as cursor:
|
|
|
|
|
+ cursor.execute(query, args)
|
|
|
|
|
+ if commit:
|
|
|
|
|
+ conn.commit()
|
|
|
|
|
+ self.log.debug(f"sql _execute, Query: {query}, Rows: {cursor.rowcount}")
|
|
|
|
|
+ return cursor
|
|
|
|
|
+ except pymysql.err.InterfaceError as e:
|
|
|
|
|
+ # 连接已断开,重试一次
|
|
|
|
|
+ if attempt == 0:
|
|
|
|
|
+ self.log.warning(f"数据库连接断开,正在重试... Error: {e}")
|
|
|
|
|
+ continue
|
|
|
|
|
+ self.log.error(f"重试后仍失败: {e}, Query: {query}")
|
|
|
|
|
+ raise e
|
|
|
|
|
+ except pymysql.err.IntegrityError:
|
|
|
|
|
+ # 完整性错误(如重复条目)交由上层处理,避免在此打印完整堆栈污染日志
|
|
|
|
|
+ if commit and conn:
|
|
|
|
|
+ try:
|
|
|
|
|
+ conn.rollback()
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+ pass
|
|
|
|
|
+ raise
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ if commit and conn:
|
|
|
|
|
+ try:
|
|
|
|
|
+ conn.rollback()
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+ pass
|
|
|
|
|
+ self.log.exception(f"Error executing query: {e}, Query: {query}, Args: {args}")
|
|
|
|
|
+ raise e
|
|
|
|
|
|
|
|
def select_one(self, query, args=None):
|
|
def select_one(self, query, args=None):
|
|
|
"""
|
|
"""
|
|
@@ -183,13 +222,14 @@ class MySQLConnectionPool:
|
|
|
return cursor.lastrowid
|
|
return cursor.lastrowid
|
|
|
except pymysql.err.IntegrityError as e:
|
|
except pymysql.err.IntegrityError as e:
|
|
|
if "Duplicate entry" in str(e):
|
|
if "Duplicate entry" in str(e):
|
|
|
- self.log.warning(f"插入失败:重复条目,已跳过。错误详情: {e}")
|
|
|
|
|
|
|
+ # 重复条目用 warning 简短输出,不打印堆栈
|
|
|
|
|
+ self.log.warning(f"插入跳过-重复条目 Table: {table}, {e.args[1] if len(e.args) > 1 else e}")
|
|
|
return -1 # 返回 -1 表示重复条目被跳过
|
|
return -1 # 返回 -1 表示重复条目被跳过
|
|
|
else:
|
|
else:
|
|
|
- self.log.exception(f"数据库完整性错误: {e}")
|
|
|
|
|
|
|
+ self.log.error(f"数据库完整性错误 Table: {table}, Error: {e}")
|
|
|
raise
|
|
raise
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- self.log.exception(f"未知错误: {e}")
|
|
|
|
|
|
|
+ self.log.error(f"insert_one_or_dict 失败 Table: {table}, Error: {e}")
|
|
|
raise
|
|
raise
|
|
|
|
|
|
|
|
def insert_many(self, table=None, data_list=None, query=None, args_list=None, batch_size=1000, commit=True,
|
|
def insert_many(self, table=None, data_list=None, query=None, args_list=None, batch_size=1000, commit=True,
|
|
@@ -621,30 +661,11 @@ class MySQLConnectionPool:
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if __name__ == '__main__':
|
|
|
sql_pool = MySQLConnectionPool()
|
|
sql_pool = MySQLConnectionPool()
|
|
|
- # data_dic = {'card_type_id': 111, 'card_type_name': '补充包 继承的意志【OPC-13】', 'card_type_position': 964,
|
|
|
|
|
- # 'card_id': 5284, 'card_name': '蒙奇·D·路飞', 'card_number': 'OP13-001', 'card_rarity': 'L',
|
|
|
|
|
- # 'card_img': 'https://source.windoent.com/OnePiecePc/Picture/1757929283612OP13-001.png',
|
|
|
|
|
- # 'card_life': '4', 'card_attribute': '打', 'card_power': '5000', 'card_attack': '-',
|
|
|
|
|
- # 'card_color': '红/绿', 'subscript': 4, 'card_features': '超新星/草帽一伙',
|
|
|
|
|
- # 'card_text_desc': '【咚!!×1】【对方的攻击时】我方处于活跃状态的咚!!不多于5张的场合,可以将我方任意张数的咚!!转为休息状态。每有1张转为休息状态的咚!!,本次战斗中,此领袖或我方最多1张拥有《草帽一伙》特征的角色力量+2000。',
|
|
|
|
|
- # 'card_offer_type': '补充包 继承的意志【OPC-13】', 'crawler_language': '简中'}
|
|
|
|
|
- # sql_pool.insert_one_or_dict(table="one_piece_record", data=data_dic)
|
|
|
|
|
-
|
|
|
|
|
- sql_pool.insert_many(
|
|
|
|
|
- table="jhs_product_record",
|
|
|
|
|
- data_list=[
|
|
|
|
|
- {
|
|
|
|
|
- "product_id": 99999991,
|
|
|
|
|
- "seller_username": "浣熊小助理(裸卡版)",
|
|
|
|
|
- "auction_product_name": "2000 日文 无编号 #175 U 波克比 有瑕疵",
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- "product_id": 99999992,
|
|
|
|
|
- "seller_username": "测试商家二号",
|
|
|
|
|
- "auction_product_name": "中文批量插入测试",
|
|
|
|
|
- },
|
|
|
|
|
- ],
|
|
|
|
|
- ignore=False
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ data_dic = {'card_type_id': 111, 'card_type_name': '补充包 继承的意志【OPC-13】', 'card_type_position': 964,
|
|
|
|
|
+ 'card_id': 5284, 'card_name': '蒙奇·D·路飞', 'card_number': 'OP13-001', 'card_rarity': 'L',
|
|
|
|
|
+ 'card_img': 'https://source.windoent.com/OnePiecePc/Picture/1757929283612OP13-001.png',
|
|
|
|
|
+ 'card_life': '4', 'card_attribute': '打', 'card_power': '5000', 'card_attack': '-',
|
|
|
|
|
+ 'card_color': '红/绿', 'subscript': 4, 'card_features': '超新星/草帽一伙',
|
|
|
|
|
+ 'card_text_desc': '【咚!!×1】【对方的攻击时】我方处于活跃状态的咚!!不多于5张的场合,可以将我方任意张数的咚!!转为休息状态。每有1张转为休息状态的咚!!,本次战斗中,此领袖或我方最多1张拥有《草帽一伙》特征的角色力量+2000。',
|
|
|
|
|
+ 'card_offer_type': '补充包 继承的意志【OPC-13】', 'crawler_language': '简中'}
|
|
|
|
|
+ sql_pool.insert_one_or_dict(table="one_piece_record", data=data_dic)
|