注意避坑,peewee 直接操作 db 对象运行原生 sql 的时候,ReconnectMySQLDatabase 会失效 ,比如 with db.cursor() as cursor
我使用 ReconnectMixin 和 MySQLDatabase 构建了一个 ReconnectMySQLDatabase 来实现 mysql 的断连下的自动重连
import peewee
from peewee import Model, MySQLDatabase
from peewee import CharField, IntegerField, DateTimeField, AutoField, DateField
from peewee import BooleanField, SmallIntegerField, TextField
from peewee import SQL
import settings
from playhouse.shortcuts import ReconnectMixin
class ReconnectMySQLDatabase(ReconnectMixin, MySQLDatabase):
pass
db = ReconnectMySQLDatabase(
database=settings.MYSQL_TKDB_CONFIG.database_name,
host=settings.MYSQL_TKDB_CONFIG.host,
port=settings.MYSQL_TKDB_CONFIG.port,
user=settings.MYSQL_TKDB_CONFIG.username,
password=settings.MYSQL_TKDB_CONFIG.password,
charset='utf8mb4'
)
上面的代码在使用 orm 的原生写法的时候,没有问题
# 可以实现自动重连
SeriesTable.select().where(
SeriesTable.status == status)
但是要注意的是,如果使用 db 对象直接去操作 sql,那就不会重连了
from pymysql.cursors import Cursor
sql = """
UPDATE xxxx s
JOIN (
SELECT id
FROM xxxx
WHERE xxxx = 'xxxxx'
AND xxxxx = 'xxxxx'
LIMIT 500
) AS limited_ids ON s.id = limited_ids.id
SET s.xxxx = 'xxxxx';
"""
# logger.debug(f'sql: {sql}')
with db.cursor() as cursor:
cursor: Cursor
cursor.execute(sql)
cursor.connection.commit() # 这里必须要提交,不然所有的查询都会处于一个事务中
affected = cursor.rowcount
上面直接执行 sql 的代码,可能会报错如下:
raise value.with_traceback(tb)
File "/usr/local/lib/python3.11/site-packages/peewee.py", line 3322, in execute_sql
cursor.execute(sql, params or ())
File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 153, in execute
result = self._query(query)
^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 562, in query
self._execute_command(COMMAND.COM_QUERY, sql)
File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 843, in _execute_command
raise err.InterfaceError(0, "")
peewee.InterfaceError: (0, '')
参考文章: