小陆同学

python 中文名:蟒蛇,设计者:Guido van Rossum

导航

使用flask sqlalchemy过程中遇到的问题

 

程序背景:

2个定时任务分别去执行两个数据库的操作,使用的定时任务工具是:
from apscheduler.schedulers.background import BackgroundScheduler(非阻塞)
from apscheduler.schedulers.blocking import BlockingScheduler(阻塞)
 
2个定时任务,其中一个数据量较少的任务a,每次的请求都能成功,另外一个数据量较大的任务b,定时任务的周期较长,每每b任务都执行不成功。
 

报错如下:

pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')

我尝试过的办法:

 
经过查询https://blog.csdn.net/qq_37287621/article/details/104805160,该报错说明程序和mysql的链接断开了,于是我照着网上的流程,去查询数据库的链接时长
SHOW SESSION VARIABLES LIKE '%timeout%';
查询显示:wait_timeout变量的值是300,也就是5分钟。网上的解决方式:
修改数据库连接池的配置,数据库连接池都会带有一个参数:回收时间(就是一定时间内不使用就会回收),修改这个参数的值,不要大于wait_timeout的值即可。在flask-SQLAlchemy中有个配置是SQLALCHEMY_POOL_RECYCLE(多之后对线程池中的线程进行一次连接的回收),如果这个值是-1代表永不回收,Flask-SQLALchemy 自动设定这个值为2小时,我们可以将这个值设置的小于wait_timeout参数的值也就是5分钟即可。
我在flask程序中配置了
app.config['SQLALCHEMY_POOL_RECYCLE'] = 200 (小于数据库连接)
然而并没有什么作用,为啥2个定时任务中,a任务也需要跟数据库交互,但不存在交互断开的问题。
几经查询,看到网上一位网友吐槽了,大数据量情况下的频繁插入、频繁commit,造成数据库的链接断开,或者丢数据的场景,这位网友用了计数器,如:每100次add,一次commit。https://blog.csdn.net/ywdhzxf/article/details/85012255
 
 

于是,我通过以下方法成功的解决了这一问题:

1、调整定时任务的间隔时间
2、优化批量插入:
class TableA(db.Model):
  __tablename__ = "table_a"
  id = db.Column(db.INTEGER,primary_key=True, autoincrement=True)
  name = db.Column(db.String(255))
  age = db.Column(db.Text)
  create_time = db.Column(db.DateTime,default=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  def create_obj(self,datalist): # datalist=[{"name":"张三","age":"1"}]
    from start import app
    with app.app_context():
      db.session.execute(TableA.__table__.insert(),datalist)
      db.session.commit()

 

posted on 2022-05-27 19:02  小陆同学  阅读(703)  评论(0编辑  收藏  举报