最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Python peewee 使用經(jīng)驗

 更新時間:2017年10月20日 11:51:02   作者:削微寒  
這篇文章主要介紹了淺談Python peewee 使用經(jīng)驗,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文使用案例是基于 python2.7 實現(xiàn)

以下內(nèi)容均為個人使用 peewee 的經(jīng)驗和遇到的坑,不會涉及過多的基本操作。所以,沒有使用過 peewee,可以先閱讀文檔

正確性和覆蓋面有待提高,如果遇到新的問題歡迎討論。

一、介紹

Peewee 是一個簡單、輕巧的 Python ORM。

  1. 簡單、輕巧、富有表現(xiàn)力(原詞 expressive )的ORM
  2. 支持python版本 2.6+ 和 3.2+
  3. 支持?jǐn)?shù)據(jù)庫包括:sqlite, mysql and postgresql
  4. 包含一堆實用的擴(kuò)展在 playhouse 模塊中

總而言之,peewee 可以完全可以應(yīng)付個人或企業(yè)的中小型項目的 Model 層,上手容易,功能很強(qiáng)大。

二、基本使用方法

from peewee import *

db = SqliteDatabase('people.db')
class BaseModel(Model):
  class Meta:
    database = db # This model uses the "people.db" database.

class Person(BaseModel):
  name = CharField()
  birthday = DateField()
  is_relative = BooleanField()  

基本的使用方法,推薦閱讀文檔--quickstart

三、推薦使用姿勢

下面介紹一些我在使用過程的經(jīng)驗和遇到的坑,希望可以幫助大家更好的使用 peewee。

3.1 連接數(shù)據(jù)庫

連接數(shù)據(jù)庫時,推薦使用 playhouse 中的 db_url 模塊。db_url 的 connect 方法可以通過傳入的 URL 字符串,生成數(shù)據(jù)庫連接。

3.1.1 connect(url, **connect_params)

通過傳入的 url 字符串,創(chuàng)建一個數(shù)據(jù)庫實例

url形如:

  1. mysql://user:passwd@ip:port/my_db 將創(chuàng)建一個 本地 MySQL 的 my_db 數(shù)據(jù)庫的實例(will create a MySQLDatabase instance)
  2. mysql+pool://user:passwd@ip:port/my_db?charset=utf8&max_connections=20&stale_timeout=300 將創(chuàng)建一個本地 MySQL 的 my_db 的連接池,最大連接數(shù)為20(In a multi-threaded application, up to max_connections will be opened. Each thread (or, if using gevent, greenlet) will have it's own connection. ),超時時間為300秒(will create a PooledMySQLDatabase instance)

注意:charset 默認(rèn)為utf8。如需要支持 emoji ,charset 設(shè)置為utf8mb4,同時保證創(chuàng)建數(shù)據(jù)庫時的字符集設(shè)置正確CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。

支持的 schemes:

  1. apsw: APSWDatabase
  2. mysql: MySQLDatabase
  3. mysql+pool: PooledMySQLDatabase
  4. postgres: PostgresqlDatabase
  5. postgres+pool: PooledPostgresqlDatabase
  6. postgresext: PostgresqlExtDatabase
  7. postgresext+pool: PooledPostgresqlExtDatabase
  8. sqlite: SqliteDatabase
  9. sqliteext: SqliteExtDatabase
  10. sqlite+pool: PooledSqliteDatabase
  11. sqliteext+pool: PooledSqliteExtDatabase

3.1.2 推薦姿勢

from playhouse.db_url import connect

from dock.common import config

# url: mysql+pool://root:root@127.0.0.1:3306/appmanage?max_connections=300&stale_timeout=300
mysql_config_url = config_dict.get('config').get('mysql').get('url')
db = connect(url=mysql_config_url)

查看更多詳情請移步官方文檔:db-url

3.2 連接池的使用

peewee 的連接池,使用時需要顯式的關(guān)閉連接。下面先說下為什么,最后會給出推薦的使用方法,避免進(jìn)坑。

3.2.1 為什么要顯式的關(guān)閉連接

Connections will not be closed exactly when they exceed their stale_timeout. Instead, stale connections are only closed when a new connection is requested.

這里引用官方文檔的提示。大致說:“超時連接不會自動關(guān)閉,只會在有新的請求時是才會關(guān)閉”。這里的request是指‘web 框架處理的請求',peewee 源碼片段:

def _connect(self, *args, **kwargs):
  while True:
    try:
      # Remove the oldest connection from the heap.
      ts, conn = heapq.heappop(self._connections) # _connections是連接實例的list(pool)
      key = self.conn_key(conn)
    except IndexError:
      ts = conn = None
      logger.debug('No connection available in pool.')
      break
    else:
      if self._is_closed(key, conn):
        # This connecton was closed, but since it was not stale
        # it got added back to the queue of available conns. We
        # then closed it and marked it as explicitly closed, so
        # it's safe to throw it away now.
        # (Because Database.close() calls Database._close()).
        logger.debug('Connection %s was closed.', key)
        ts = conn = None
        self._closed.discard(key)
      elif self.stale_timeout and self._is_stale(ts):
        # If we are attempting to check out a stale connection,
        # then close it. We don't need to mark it in the "closed"
        # set, because it is not in the list of available conns
        # anymore.
        logger.debug('Connection %s was stale, closing.', key)
        self._close(conn, True)
        self._closed.discard(key)
        ts = conn = None
      else:
        break
  if conn is None:
    if self.max_connections and (
        len(self._in_use) >= self.max_connections):
      raise ValueError('Exceeded maximum connections.')
    conn = super(PooledDatabase, self)._connect(*args, **kwargs)
    ts = time.time()
    key = self.conn_key(conn)
    logger.debug('Created new connection %s.', key)

  self._in_use[key] = ts # 使用中的數(shù)據(jù)庫連接實例dict
  return conn

根據(jù) pool 庫中的 _connect 方法的代碼可知:每次在建立數(shù)據(jù)庫連接時,會檢查連接實例是否超時。但是需要注意一點:使用中的數(shù)據(jù)庫連接實例(_in_use dict中的數(shù)據(jù)庫連接實例),是不會在創(chuàng)建數(shù)據(jù)庫連接時,檢查是否超時的。

因為這段代碼中,每次創(chuàng)建連接實例,都是在 _connections(pool) 取實例,如果有的話就判斷是否超時;如果沒有的話就新建。

然而,使用中的數(shù)據(jù)庫連接并不在 _connections 中,所以每次創(chuàng)建數(shù)據(jù)庫連接實例時,并沒有檢測使用中的數(shù)據(jù)庫連接實例是否超時。

只有調(diào)用連接池實例的 _close 方法。執(zhí)行這個方法后,才會把使用后的連接實例放回到 _connections (pool)。

def _close(self, conn, close_conn=False):
  key = self.conn_key(conn)
  if close_conn:
    self._closed.add(key)
    super(PooledDatabase, self)._close(conn) # 關(guān)閉數(shù)據(jù)庫連接的方法
  elif key in self._in_use:
    ts = self._in_use[key]
    del self._in_use[key]
    if self.stale_timeout and self._is_stale(ts):  # 到這里才會判斷_in_use中的連接實例是否超時
      logger.debug('Closing stale connection %s.', key)
      super(PooledDatabase, self)._close(conn)  # 超時的話,關(guān)閉數(shù)據(jù)庫連接
    else:
      logger.debug('Returning %s to pool.', key)
      heapq.heappush(self._connections, (ts, conn)) # 沒有超時的話,放回到pool中

3.2.2 如果不顯式的關(guān)閉連接,會出現(xiàn)的問題

如果不調(diào)用_close方法的話,使用后 的數(shù)據(jù)庫連接就一直不會關(guān)閉(兩個含義:回到pool中和關(guān)閉數(shù)據(jù)庫連接),這樣會造成兩個問題:

1.每次都是新建數(shù)據(jù)庫連接,因為 pool 中沒有數(shù)據(jù)庫連接實例。會導(dǎo)致稍微有一點并發(fā)量就會返回Exceeded maximum connections.錯誤

2.MySQL也是有 timeout 的,如果一個連接長時間沒有請求的話,MySQL Server 就會關(guān)閉這個連接,但是,peewee的已建立(后面會解釋為什么特指已建立的)的連接實例,并不知道 MySQL Server 已經(jīng)關(guān)閉了,再去通過這個連接請求數(shù)據(jù)的話,就會返回 Error 2006: “MySQL server has gone away”錯誤,根據(jù)官方文檔

3.2.3 推薦姿勢

所以,每次操作完數(shù)據(jù)庫就關(guān)閉連接實例。

用法1:使用with

def send_rule():
  with db.execution_context():
  # 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.
    for user in get_all_user():
      user_id = user['id']
      rule = Rule(user_id)
      rule_dict = rule.slack_rule(index)
      .....do something.....

用法2:使用Flask hook

@app.before_request
def _db_connect():
  database.connect()
#
# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.teardown_request
def _db_close(exc):
  if not database.is_closed():
    database.close()
#
#
# 更優(yōu)雅的用法:
from playhouse.flask_utils import FlaskDB
from dock_fastgear.model.base import db
#
app = Flask(__name__)
FlaskDB(app, db) # 這樣就自動做了上面的事情(具體實現(xiàn)可查看http://docs.peewee-orm.com/en/latest/peewee/playhouse.html?highlight=Flask%20DB#flask-utils)

查看更多詳情請移步官方文檔:pool-apis

3.3 處理查詢結(jié)果

這里沒有什么大坑,就是有兩點需要注意:

首先,查詢的結(jié)果都是該 Model 的 object,注意不是 dict。如果想讓結(jié)果為 dict,需要 playhouse 模塊的工具方法進(jìn)行轉(zhuǎn)化:from playhouse.shortcuts import model_to_dict

其次,get方法只會返回一條記錄

3.3.1 推薦姿勢

from playhouse.shortcuts import model_to_dict
from model import HelloGitHub

def read_from_db(input_vol):
  content_list = []
  category_object_list = HelloGitHub.select(HelloGitHub.category).where(HelloGitHub.vol == input_vol)\
    .group_by(HelloGitHub.category).order_by(HelloGitHub.category)

  for fi_category_object in category_object_list:
    hellogithub = HelloGitHub.select()\
      .where((HelloGitHub.vol == input_vol)
          & (HelloGitHub.category == fi_category_object.category))\
      .order_by(HelloGitHub.create_time)
    for fi_hellogithub in hellogithub:
      content_list.append(model_to_dict(fi_hellogithub))
  return content_list

四、常見錯誤及解決辦法

4.1 'buffer' object has no attribute 'translate'

  1. 錯誤信息: "'buffer' object has no attribute 'translate'"
  2. 場景:BlobField 字段存儲zlib compress壓縮的數(shù)據(jù)
  3. 解決辦法:需要指定pymysql的版本小于0.6.7 否則會報錯
  4. 參考

4.2 Can't connect to MySQL server Lost connection to MySQL server during query

  1. 錯誤信息:Can't connect to MySQL server Lost connection to MySQL server during query
  2. 場景:向 RDS 中插入數(shù)據(jù)
  3. 解決辦法:因為請求的連接數(shù)過多,達(dá)到了 RDS 設(shè)置的連接數(shù),所以需要調(diào)高 RDS 連接數(shù)
  4. 參考

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python爬蟲之Selenium鼠標(biāo)事件的實現(xiàn)

    Python爬蟲之Selenium鼠標(biāo)事件的實現(xiàn)

    這篇文章主要介紹了Python爬蟲之Selenium鼠標(biāo)事件的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Pytest單元測試框架生成HTML測試報告及優(yōu)化的步驟

    Pytest單元測試框架生成HTML測試報告及優(yōu)化的步驟

    本文主要介紹了Pytest單元測試框架生成HTML測試報告及優(yōu)化的步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • python使用ctypes庫調(diào)用DLL動態(tài)鏈接庫

    python使用ctypes庫調(diào)用DLL動態(tài)鏈接庫

    這篇文章主要介紹了python如何使用ctypes庫調(diào)用DLL動態(tài)鏈接庫,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-10-10
  • AI與Python計算機(jī)視覺教程

    AI與Python計算機(jī)視覺教程

    這篇文章主要為大家介紹了AI與Python計算機(jī)視覺教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Python按照list dict key進(jìn)行排序過程解析

    Python按照list dict key進(jìn)行排序過程解析

    這篇文章主要介紹了Python按照list dict key進(jìn)行排序過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • 一文帶你解決Python中的所有報錯

    一文帶你解決Python中的所有報錯

    使用Python進(jìn)行代碼編程的時候,難免會遇到代碼報錯,不僅僅是新手小白會遇到,就是很多編程大神也是經(jīng)常出現(xiàn)BUG的,下面這篇文章主要給大家介紹了關(guān)于解決Python中所有報錯的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • Python海象運(yùn)算符代碼分析及知識點總結(jié)

    Python海象運(yùn)算符代碼分析及知識點總結(jié)

    在本篇內(nèi)容里小編給大家總結(jié)了關(guān)于Python海象運(yùn)算符的使用的相關(guān)內(nèi)容及代碼,有興趣的朋友們跟著學(xué)習(xí)下。
    2022-11-11
  • python執(zhí)行shell獲取硬件參數(shù)寫入mysql的方法

    python執(zhí)行shell獲取硬件參數(shù)寫入mysql的方法

    這篇文章主要介紹了python執(zhí)行shell獲取硬件參數(shù)寫入mysql的方法,可實現(xiàn)對服務(wù)器硬件信息的讀取及寫入數(shù)據(jù)庫的功能,非常具有實用價值,需要的朋友可以參考下
    2014-12-12
  • Python科學(xué)計算之Pandas詳解

    Python科學(xué)計算之Pandas詳解

    Pandas 是 python 的一個數(shù)據(jù)分析包,屬于PyData項目的一部分。下面這篇文章主要介紹了Python中科學(xué)計算之Pandas,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)。
    2017-01-01
  • PyTorch環(huán)境中CUDA版本沖突問題排查與解決方案

    PyTorch環(huán)境中CUDA版本沖突問題排查與解決方案

    在使用 PyTorch 進(jìn)行深度學(xué)習(xí)開發(fā)時,CUDA 版本兼容性問題是個老生常談的話題,本文將通過一次真實的排查過程,剖析 PyTorch 虛擬環(huán)境自帶 CUDA 運(yùn)行時庫與系統(tǒng)全局 CUDA 環(huán)境沖突的場景,需要的朋友可以參考下
    2025-02-02

最新評論

务川| 北票市| 昌吉市| 邯郸县| 商丘市| 麟游县| 温宿县| 日喀则市| 舞阳县| 得荣县| 红安县| 洛宁县| 绥棱县| 旌德县| 凤台县| 邵武市| 彩票| 长顺县| 武义县| 墨竹工卡县| 新河县| 德昌县| 西宁市| 湘西| 普兰店市| 珠海市| 行唐县| 定兴县| 商都县| 阿鲁科尔沁旗| 宁武县| 界首市| 镇远县| 银川市| 外汇| 甘德县| 大丰市| 启东市| 连云港市| 东安县| 进贤县|