peewee mysql自动断开_flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
這篇主要介紹在這次項(xiàng)目中使用的peewee
首先我們要初始化一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象。這里我使用了peewee提供的鏈接池。當(dāng)然你也可以直接指定連接例如:
db = SqliteDatabase('base.db')
我這里使用了peewee擴(kuò)展pool,并初始化db對(duì)象參數(shù)。
from playhouse importpool
db= 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'])
然后建一個(gè)peewee的基類
#建議自己的項(xiàng)目使用一個(gè)新的基類,Model是peewee的基類
classBaseModel(Model):classMeta:
database=db
@classmethoddef getOne(cls, *query, **kwargs):#為了方便使用,新增此接口,查詢不到返回None,而不拋出異常
try:return cls.get(*query,**kwargs)exceptDoesNotExist:return None
然后就可以使用類繼承BaseModel建立表了
classXcfRootCategory(BaseModel):classMeta:
db_table= 'xcf_root_category'xcf_category_id= IntegerField() #下廚房十九宮格一級(jí)分類ID
name = CharField(null=False)
這里覺(jué)得值得一講的只有特殊的Meta,Peewee文檔里面提供了非常多的Meta類型可以使用。這里的意思是指定了db_table是在數(shù)據(jù)庫(kù)里名叫xcf_root_category的表然后對(duì)應(yīng)起來(lái),這個(gè)類下面的方法,操作的其實(shí)就是對(duì)應(yīng)的xcf_root_category這張表的內(nèi)容。類的實(shí)例也就是這張表的實(shí)例。
其他參數(shù)可以查詢文檔得到不贅述。
之后我嘗試給這張表添加一些方法
@classmethoddefupdate_name(cls, xcf_category_id, name):try:
XcfRootCategory.update(name=name).where(XcfRootCategory.xcf_category_id ==xcf_category_id).execute()returnTrueexcept:return False
這是官方推薦的寫(xiě)法。雖然有點(diǎn)奇怪,但是據(jù)說(shuō)效率不錯(cuò)。
這里的語(yǔ)句更新了一條記錄
其他也沒(méi)有遇到什么坑,唯一可能會(huì)比較讓人頭痛的就是peewee在對(duì)mysql進(jìn)行連接發(fā)生著名的ERROR2006的問(wèn)題,
Error 2006:?MySQL?server has?gone?away
這里其實(shí)官方介紹了兩種方法解決,在2016年1月17號(hào)的時(shí)候,同樣遇到該問(wèn)題的朋友還向官方發(fā)了一個(gè)修復(fù)的pr現(xiàn)在已經(jīng)合并,估計(jì)下次發(fā)版會(huì)修復(fù)
地址:https://github.com/coleifer/peewee/pull/822
著重講一下這個(gè)pr到底是修復(fù)了什么問(wèn)題呢?
在這個(gè)issue被修復(fù)之前,如果你使用peewee連接會(huì)很容易發(fā)現(xiàn),當(dāng)你在發(fā)起了一次request操作之后,一段時(shí)間不操作,正好你的數(shù)據(jù)庫(kù)的wait_timeout超時(shí)時(shí)間又設(shè)置得比較短,那么在你下次請(qǐng)求的時(shí)候就會(huì)出現(xiàn)Error 2006: mysql server has gone away的錯(cuò)誤。即使你按照官方文檔使用了鉤子或者更細(xì)粒度的線程管理,也無(wú)法阻止這個(gè)問(wèn)題。因?yàn)榇a本身有個(gè)bug,就是無(wú)法正確的判斷連接是不是已經(jīng)斷掉了。也就是說(shuō)當(dāng)mysql到達(dá)了超時(shí)的時(shí)間,但是peewee的連接管理并不知道這個(gè)情況,由于peewee在請(qǐng)求第一次之后就是一直維持連接是打開(kāi)的狀態(tài),所以當(dāng)你試圖繼續(xù)使用這個(gè)連接發(fā)起sql操作的時(shí)候,連接實(shí)際上被關(guān)閉了,然后就報(bào)錯(cuò)了。在現(xiàn)在github上的2.80版本已經(jīng)修復(fù)了該問(wèn)題,可以正確判斷和mysql的連接是否已經(jīng)斷開(kāi),所以再結(jié)合官方的方法,將不會(huì)再出現(xiàn)無(wú)法知曉數(shù)據(jù)庫(kù)連接是否已經(jīng)斷開(kāi)的問(wèn)題。
我這次使用的是結(jié)合框架的顯示打開(kāi)關(guān)閉連接避免這個(gè)問(wèn)題。
其實(shí)官方文檔提供了兩種方法,一種是基于框架的,使用request hooks解決,基本原理就是在開(kāi)啟一次請(qǐng)求的時(shí)候,在開(kāi)啟前用鉤子函數(shù)手動(dòng)顯示的的打開(kāi)
數(shù)據(jù)庫(kù)連接,然后在結(jié)束請(qǐng)求的時(shí)候顯示指明關(guān)閉連接。這樣可以避免發(fā)生沒(méi)有正常關(guān)閉的情況。
還有一種方法就是管理更加細(xì)粒度的線程本地連接。
下面給出貼出文檔。
Advanced Connection Management
Managing your database connections is as simple as calling?connect()?when you need to open a connection, and?close()?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?ExecutionContext.
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?ExecutionContextwill be pulled from the pool of available connections and recycled appropriately.
以上。
總結(jié)
以上是生活随笔為你收集整理的peewee mysql自动断开_flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一直在构建工作空间_智能工作空间让Dro
- 下一篇: mysql存储过程注释方法_mysql存