国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

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

2019-11-25 17:35:50
字體:
來源:轉載
供稿:網友

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

user = User.get('123')

而不是寫SQL然后再轉換成User對象:

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

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

和設計db模塊類似,設計ORM也是從上層調用者角度來設計。

我們先考慮如何定義一個User對象,然后把數據庫表users和它關聯起來。

from transwarp.orm import Model, StringField, IntegerFieldclass User(Model):  __table__ = 'users'  id = IntegerField(primary_key=True)  name = StringField()

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

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

實現ORM模塊

有了定義,我們就可以開始實現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的功能,同時又實現了特殊方法__getattr__()和__setattr__(),所以又可以像引用普通字段那樣寫:

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

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掃描映射關系,并存儲到自身的class中。

然后,我們往Model類添加class方法,就可以讓所有子類調用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類就可以通過類方法實現主鍵查找:

user = User.get('123')

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

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實例存入數據庫:

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

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

  find_first()  find_all()  find_by()

對于count,可以實現:

  

 count_all() count_by()

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宕昌县| 井冈山市| 龙门县| 连城县| 高要市| 隆安县| 临邑县| 通化县| 广德县| 陵水| 敦化市| 沾益县| 和静县| 琼中| 阳谷县| 阿瓦提县| 卓尼县| 政和县| 大洼县| 昆山市| 镇原县| 新泰市| 祥云县| 杭锦后旗| 花莲市| 邵阳县| 清苑县| 长宁县| 贡嘎县| 永宁县| 措勤县| 红河县| 永川市| 延津县| 彰化市| 常州市| 图们市| 乌审旗| 衡水市| 内丘县| 保亭|