> 本文环境python2版本,peewee 2.0.6系列
原本想写一下django的orm源代码,但是django的orm代码太庞大了,所以选了一个轻量级的orm,代码量小,
但是实现原理基本相似,peewee已经发行了138个版本到3.8.2版本了,最新版本的代码也多了些“繁文缛节”,
随意选了低版本的实现功能代码,原想选最低版本0.9.6,但随便点了一个2.0.6版本,代码量反而少了许多,
而且功能实现已完善,所以就选用了2.0.6版本
这里我们使用peewee中提供example中的?
DATABASE = 'tweepee.db'
# create a peewee database instance -- our models will use this database to
# persist information
database = SqliteDatabase(DATABASE) # 连接数据库
# the user model specifies its fields (or columns) declaratively, like django
class User(Model): # 设计表结构
username = CharField()
password = CharField()
email = CharField()
join_date = DateTimeField()
class Meta:
order_by = ('username',)
# it often makes sense to put convenience methods on model instances, for
# example, "give me all the users this user is following":
def following(self):
# query other users through the "relationship" table
return User.select().join(
Relationship, on=Relationship.to_user,
).where(Relationship.from_user == self)
# simple utility function to create tables
def create_tables(): # 连接数据库并创建表结构
database.connect()
User.create_table()
上面的?展示的是 连接数据库—设计表结构–连接并创建表结构,下面我们先从设计表机构开始分析。看一下User表创建的过程中发生了什么,下面看一下继承的函数Model
class Model(object):
__metaclass__ = BaseModel # __metaclass__ 指定元类
# python2.x版本用法,python3.x使用 class Model(objcet, BaseModel)
def __init__(self, *args, **kwargs): # 实例初始化函数
self._data = self._meta.get_default_dict() # 获取预设的内容,self._meta,后面会讲,是一个ModelOptions()实例
self._obj_cache = {} # cache of related objects
for k, v in kwargs.items(): # 获取新的参数内容
setattr(self, k, v)
Model()类中有一个很特殊的地方,metaclass = BaseModel,这个是什么意思呢,这里有一篇很棒的博客http://blog.jobbole.com/21351/,给大家讲解一下__metaclass__的具体使用方法。简单讲:__metaclass__就是定义了一个类似与type的元类,这个元类的主要作用就是生成继承了它的类。这个方法在Django的orm中同样有使用到。下面看一下BaseModel类。
重点重点来了!!!
我们需要用BaseModel来创建Model这个类. 此时, 传递给BaseModel的__new__方法的参数为: “Model”, object, Model里定义的类方法的一个字典. 这里删减了一部分未用到的代码,在创建User类的时候会用到,再仔细讲。
class BaseModel(type):
inheritable_options = ['database', 'indexes', 'order_by', 'primary_key']
def __new__(cls, name, bases, attrs):
meta_options = {}
meta = attrs.pop('Meta', None)
if meta:
meta_options.update((k, v) for k, v in meta.__dict__.items() if not k.startswith('_'))
# initialize the new class and set the magic attributes
cls = super(BaseModel, cls).__new__(cls, name, bases, attrs) # 返回Model类实例
cls._meta = ModelOptions(cls, **meta_options) # 为实例添加_meta属性,_meta其实是ModelOptions()的一个实例
cls._data = None
primary_key = None
if not primary_key:
primary_k