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

Python中編寫ORM框架的入門指引

 更新時間:2015年04月29日 17:10:39   作者:廖雪峰  
這篇文章主要介紹了Python中編寫ORM框架的入門指引,示例代碼基于Python2.x版本,需要的朋友可以參考下

有了db模塊,操作數(shù)據(jù)庫直接寫SQL就很方便。但是,我們還缺少ORM。如果有了ORM,就可以用類似這樣的語句獲取User對象:

user = User.get('123')

而不是寫SQL然后再轉(zhuǎn)換成User對象:

u = db.select_one('select * from users where id=?', '123')
user = User(**u)

所以我們開始編寫ORM模塊:transwarp.orm。
設(shè)計ORM接口

和設(shè)計db模塊類似,設(shè)計ORM也是從上層調(diào)用者角度來設(shè)計。

我們先考慮如何定義一個User對象,然后把數(shù)據(jù)庫表users和它關(guān)聯(lián)起來。

from transwarp.orm import Model, StringField, IntegerField

class User(Model):
  __table__ = 'users'
  id = IntegerField(primary_key=True)
  name = StringField()

注意到定義在User類中的__table__、id和name是類的屬性,不是實例的屬性。所以,在類級別上定義的屬性用來描述User對象和表的映射關(guān)系,而實例屬性必須通過__init__()方法去初始化,所以兩者互不干擾:

# 創(chuàng)建實例:
user = User(id=123, name='Michael')
# 存入數(shù)據(jù)庫:
user.insert()

實現(xiàn)ORM模塊

有了定義,我們就可以開始實現(xiàn)ORM模塊。

首先要定義的是所有ORM映射的基類Model:

class Model(dict):
  __metaclass__ = ModelMetaclass

  def __init__(self, **kw):
    super(Model, self).__init__(**kw)

  def __getattr__(self, key):
    try:
      return self[key]
    except KeyError:
      raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

  def __setattr__(self, key, value):
    self[key] = value

Model從dict繼承,所以具備所有dict的功能,同時又實現(xiàn)了特殊方法__getattr__()和__setattr__(),所以又可以像引用普通字段那樣寫:

>>> user['id']
123
>>> user.id
123

Model只是一個基類,如何將具體的子類如User的映射信息讀取出來呢?答案就是通過metaclass:ModelMetaclass:

class ModelMetaclass(type):
  def __new__(cls, name, bases, attrs):
    mapping = ... # 讀取cls的Field字段
    primary_key = ... # 查找primary_key字段
    __table__ = cls.__talbe__ # 讀取cls的__table__字段
    # 給cls增加一些字段:
    attrs['__mapping__'] = mapping
    attrs['__primary_key__'] = __primary_key__
    attrs['__table__'] = __table__
    return type.__new__(cls, name, bases, attrs)

這樣,任何繼承自Model的類(比如User),會自動通過ModelMetaclass掃描映射關(guān)系,并存儲到自身的class中。

然后,我們往Model類添加class方法,就可以讓所有子類調(diào)用class方法:

class Model(dict):

  ...

  @classmethod
  def get(cls, pk):
    d = db.select_one('select * from %s where %s=?' % (cls.__table__, cls.__primary_key__.name), pk)
    return cls(**d) if d else None

User類就可以通過類方法實現(xiàn)主鍵查找:

user = User.get('123')

往Model類添加實例方法,就可以讓所有子類調(diào)用實例方法:

class Model(dict):

  ...

  def insert(self):
    params = {}
    for k, v in self.__mappings__.iteritems():
      params[v.name] = getattr(self, k)
    db.insert(self.__table__, **params)
    return self

這樣,就可以把一個User實例存入數(shù)據(jù)庫:

user = User(id=123, name='Michael')
user.insert()

最后一步是完善ORM,對于查找,我們可以實現(xiàn)以下方法:

  find_first()

  find_all()

  find_by()

對于count,可以實現(xiàn):

  

 count_all()

 count_by()

以及update()和delete()方法。

最后看看我們實現(xiàn)的ORM模塊一共多少行代碼?加上注釋和doctest才僅僅300多行。用Python寫一個ORM是不是很容易呢?

相關(guān)文章

  • pandas實現(xiàn)按行選擇的示例代碼

    pandas實現(xiàn)按行選擇的示例代碼

    這篇文章主要介紹了pandas實現(xiàn)按行選擇的示例代碼,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • python+selenium實現(xiàn)自動化百度搜索關(guān)鍵詞

    python+selenium實現(xiàn)自動化百度搜索關(guān)鍵詞

    在本篇文章里我們給大家分享了一篇關(guān)于python+selenium實現(xiàn)自動化百度搜索關(guān)鍵詞的實例文章,需要的朋友們可以跟著操作下。
    2019-06-06
  • 利用Python實時獲取steam特惠游戲數(shù)據(jù)

    利用Python實時獲取steam特惠游戲數(shù)據(jù)

    Steam是由美國電子游戲商Valve于2003年9月12日推出的數(shù)字發(fā)行平臺,被認(rèn)為是計算機游戲界最大的數(shù)碼發(fā)行平臺之一。本文將利用Python實時獲取steam特惠游戲數(shù)據(jù),感興趣的可以嘗試一下
    2022-06-06
  • python merge、concat合并數(shù)據(jù)集的實例講解

    python merge、concat合并數(shù)據(jù)集的實例講解

    下面小編就為大家分享一篇python merge、concat合并數(shù)據(jù)集的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python HTMLTestRunner可視化報告實現(xiàn)過程解析

    Python HTMLTestRunner可視化報告實現(xiàn)過程解析

    這篇文章主要介紹了Python HTMLTestRunner可視化報告實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Python 基于win32com客戶端實現(xiàn)Excel操作的詳細(xì)過程

    Python 基于win32com客戶端實現(xiàn)Excel操作的詳細(xì)過程

    這篇文章主要介紹了Python 基于win32com客戶端實現(xiàn)Excel操作的詳細(xì)過程,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Python實現(xiàn)暴力破解wifi密碼并打包成exe

    Python實現(xiàn)暴力破解wifi密碼并打包成exe

    python號稱是編程界的萬金油,那么是否可以做個讀取電腦網(wǎng)卡wifi并暴力破解的小腳本呢?在這個基礎(chǔ)上為了方便體驗是不是可以將其打包成exe這樣方便執(zhí)行的小應(yīng)用呢?本文就來和大家一起聊聊
    2022-09-09
  • Python類的定義、繼承及類對象使用方法簡明教程

    Python類的定義、繼承及類對象使用方法簡明教程

    這篇文章主要介紹了Python類的定義、繼承及類對象使用方法簡明教程,本文用淺顯易懂的語言講解了類的定義、繼承及類對象的使用,非常實用易懂,需要的朋友可以參考下
    2015-05-05
  • 解決pyshp UnicodeDecodeError的問題

    解決pyshp UnicodeDecodeError的問題

    今天小編就為大家分享一篇解決pyshp UnicodeDecodeError的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python中順序表的實現(xiàn)簡單代碼分享

    Python中順序表的實現(xiàn)簡單代碼分享

    這篇文章主要介紹了Python中順序表的實現(xiàn)簡單代碼分享,展示了代碼運行結(jié)果,然后分享了相關(guān)實例代碼,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論

米易县| 礼泉县| 新龙县| 祁东县| 晴隆县| 永安市| 平罗县| 江西省| 临澧县| 疏附县| 调兵山市| 庆元县| 贞丰县| 聂拉木县| 普宁市| 大石桥市| 晋宁县| 鹤山市| 磴口县| 隆回县| 沈丘县| 罗城| 平远县| 那曲县| 澄江县| 红河县| 济阳县| 四会市| 涟源市| 永安市| 泸定县| 五大连池市| 锡林浩特市| 宣武区| 湘潭县| 锡林郭勒盟| 河东区| 万州区| 金乡县| 鄂伦春自治旗| 景洪市|