博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
阅读量:7115 次
发布时间:2019-06-28

本文共 4280 字,大约阅读时间需要 14 分钟。

这篇主要介绍在这次项目中使用的peewee

文档地址:

 

首先我们要初始化一个数据库连接对象。这里我使用了peewee提供的链接池。当然你也可以直接指定连接例如:

db = SqliteDatabase('base.db')

 

我这里使用了peewee扩展pool,并初始化db对象参数。

from playhouse import pooldb = pool.PooledMySQLDatabase(host=conf['host'],                              port=conf['port'],                              user=conf['user'],                              passwd=conf['passwd'],                              database=conf['database'],                              charset=conf['charset'],                              stale_timeout=conf['timeout'],                              max_connections=conf['max_connections'])

 

然后建一个peewee的基类

#建议自己的项目使用一个新的基类,Model是peewee的基类class BaseModel(Model):    class Meta:        database = db    @classmethod    def getOne(cls, *query, **kwargs):       #为了方便使用,新增此接口,查询不到返回None,而不抛出异常       try:          return cls.get(*query,**kwargs)       except DoesNotExist:           return None

 

然后就可以使用类继承BaseModel建立表了

class XcfRootCategory(BaseModel):    class Meta:        db_table = 'xcf_root_category'    xcf_category_id = IntegerField()            # 下厨房十九宫格一级分类ID    name = CharField(null=False)

这里觉得值得一讲的只有特殊的Meta,Peewee文档里面提供了非常多的Meta类型可以使用。这里的意思是指定了db_table是在数据库里名叫xcf_root_category的表然后对应起来,这个类下面的方法,操作的其实就是对应的xcf_root_category这张表的内容。类的实例也就是这张表的实例。

其他参数可以查询文档得到不赘述。

 

之后我尝试给这张表添加一些方法

@classmethod    def update_name(cls, xcf_category_id, name):        try:            XcfRootCategory.update(name=name).where(XcfRootCategory.xcf_category_id == xcf_category_id).execute()            return True        except:            return False

这是官方推荐的写法。虽然有点奇怪,但是据说效率不错。

这里的语句更新了一条记录

 

其他也没有遇到什么坑,唯一可能会比较让人头痛的就是peewee在对mysql进行连接发生著名的ERROR2006的问题,

Error 2006: MySQL server has gone away

这里其实官方介绍了两种方法解决,在2016年1月17号的时候,同样遇到该问题的朋友还向官方发了一个修复的pr现在已经合并,估计下次发版会修复

地址:https://github.com/coleifer/peewee/pull/822

着重讲一下这个pr到底是修复了什么问题呢?

在这个issue被修复之前,如果你使用peewee连接会很容易发现,当你在发起了一次request操作之后,一段时间不操作,正好你的数据库的wait_timeout超时时间又设置得比较短,那么在你下次请求的时候就会出现Error 2006: mysql server has gone away的错误。即使你按照官方文档使用了钩子或者更细粒度的线程管理,也无法阻止这个问题。因为代码本身有个bug,就是无法正确的判断连接是不是已经断掉了。也就是说当mysql到达了超时的时间,但是peewee的连接管理并不知道这个情况,由于peewee在请求第一次之后就是一直维持连接是打开的状态,所以当你试图继续使用这个连接发起sql操作的时候,连接实际上被关闭了,然后就报错了。在现在github上的2.80版本已经修复了该问题,可以正确判断和mysql的连接是否已经断开,所以再结合官方的方法,将不会再出现无法知晓数据库连接是否已经断开的问题。

 

我这次使用的是结合框架的显示打开关闭连接避免这个问题。

 

其实官方文档提供了两种方法,一种是基于框架的,使用request hooks解决,基本原理就是在开启一次请求的时候,在开启前用钩子函数手动显示的的打开

数据库连接,然后在结束请求的时候显示指明关闭连接。这样可以避免发生没有正常关闭的情况。

 

还有一种方法就是管理更加细粒度的线程本地连接。

下面给出贴出文档。

Advanced Connection Management

Managing your database connections is as simple as calling  when you need to open a connection, and  when you are finished. In a web-app, you would typically connect when you receive a request, and close the connection when you return a response. Because connection state is stored in a thread-local, you do not need to worry about juggling connection objects – peewee will handle it for you.

In some situations, however, you may want to manage your connections more explicitly. Since peewee stores the active connection in a threadlocal, this typically would mean that there could only ever be one connection open per thread. For most applications this is desirable, but if you would like to manually manage multiple connections you can create an .

Execution contexts allow finer-grained control over managing multiple connections to the database. When an execution context is initialized (either as a context manager or as a decorated function), a separate connection will be used for the duration of the wrapped block. You can also choose whether to wrap the block in a transaction.

Execution context examples:

with db.execution_context() as ctx: # A new connection will be opened or, if using a connection pool, # pulled from the pool of available connections. Additionally, a # transaction will be started. user = User.create(username='charlie') # When the block ends, the transaction will be committed and the connection # will be closed (or returned to the pool). @db.execution_context(with_transaction=False) def do_something(foo, bar): # When this function is called, a separate connection is made and will # be closed when the function returns.

If you are using the peewee connection pool, then the new connections used by the will be pulled from the pool of available connections and recycled appropriately.

 

以上。

 

转载地址:http://dwwel.baihongyu.com/

你可能感兴趣的文章
XenCenter导出虚拟机
查看>>
css中的disabled的使用
查看>>
Cookie禁用了Session还可以用吗?
查看>>
Python中*args 和**kwargs的用法
查看>>
决心书
查看>>
提高Python代码效率的方法
查看>>
如何学习Python数据分析?
查看>>
爱创课堂每日一题七十六天- 请解释什么是事件代理?
查看>>
运维39期决心书
查看>>
将数字转化为字符串
查看>>
在Linux启动或重启时执行命令与脚本
查看>>
华为拓扑---***的配置
查看>>
网站中增加微信公众账号链接的方法
查看>>
Java之品优购课程讲义_day19(3)
查看>>
finecms V5 会员头像任意文件上传漏洞 附修复代码
查看>>
购买SSL证书必须考虑的五大因素
查看>>
OpenStack简单测试性能监控数据记录
查看>>
扒一扒最近爆火的SDT-LUCK CLUB究竟是什么鬼?
查看>>
UniDAC使用教程(九):提高性能
查看>>
按照拓扑图使不同VLAN的7台PC互通
查看>>