peewee mysql自动断开_flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
這篇主要介紹在這次項目中使用的peewee
首先我們要初始化一個數(shù)據(jù)庫連接對象。這里我使用了peewee提供的鏈接池。當然你也可以直接指定連接例如:
db = SqliteDatabase('base.db')
我這里使用了peewee擴展pool,并初始化db對象參數(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'])
然后建一個peewee的基類
#建議自己的項目使用一個新的基類,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() #下廚房十九宮格一級分類ID
name = CharField(null=False)
這里覺得值得一講的只有特殊的Meta,Peewee文檔里面提供了非常多的Meta類型可以使用。這里的意思是指定了db_table是在數(shù)據(jù)庫里名叫xcf_root_category的表然后對應起來,這個類下面的方法,操作的其實就是對應的xcf_root_category這張表的內(nèi)容。類的實例也就是這張表的實例。
其他參數(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
這是官方推薦的寫法。雖然有點奇怪,但是據(jù)說效率不錯。
這里的語句更新了一條記錄
其他也沒有遇到什么坑,唯一可能會比較讓人頭痛的就是peewee在對mysql進行連接發(fā)生著名的ERROR2006的問題,
Error 2006:?MySQL?server has?gone?away
這里其實官方介紹了兩種方法解決,在2016年1月17號的時候,同樣遇到該問題的朋友還向官方發(fā)了一個修復的pr現(xiàn)在已經(jīng)合并,估計下次發(fā)版會修復
地址:https://github.com/coleifer/peewee/pull/822
著重講一下這個pr到底是修復了什么問題呢?
在這個issue被修復之前,如果你使用peewee連接會很容易發(fā)現(xiàn),當你在發(fā)起了一次request操作之后,一段時間不操作,正好你的數(shù)據(jù)庫的wait_timeout超時時間又設置得比較短,那么在你下次請求的時候就會出現(xiàn)Error 2006: mysql server has gone away的錯誤。即使你按照官方文檔使用了鉤子或者更細粒度的線程管理,也無法阻止這個問題。因為代碼本身有個bug,就是無法正確的判斷連接是不是已經(jīng)斷掉了。也就是說當mysql到達了超時的時間,但是peewee的連接管理并不知道這個情況,由于peewee在請求第一次之后就是一直維持連接是打開的狀態(tài),所以當你試圖繼續(xù)使用這個連接發(fā)起sql操作的時候,連接實際上被關閉了,然后就報錯了。在現(xiàn)在github上的2.80版本已經(jīng)修復了該問題,可以正確判斷和mysql的連接是否已經(jīng)斷開,所以再結合官方的方法,將不會再出現(xiàn)無法知曉數(shù)據(jù)庫連接是否已經(jīng)斷開的問題。
我這次使用的是結合框架的顯示打開關閉連接避免這個問題。
其實官方文檔提供了兩種方法,一種是基于框架的,使用request hooks解決,基本原理就是在開啟一次請求的時候,在開啟前用鉤子函數(shù)手動顯示的的打開
數(shù)據(jù)庫連接,然后在結束請求的時候顯示指明關閉連接。這樣可以避免發(fā)生沒有正常關閉的情況。
還有一種方法就是管理更加細粒度的線程本地連接。
下面給出貼出文檔。
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.
以上。
總結
以上是生活随笔為你收集整理的peewee mysql自动断开_flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一直在构建工作空间_智能工作空间让Dro
- 下一篇: hive 导出json格式 文件_hiv