ORM 对象关系映射
Sep 16 2014ORM概念
wikipedia: 对象关系映射
简单的说ORM就是通过操作Python中的对象来实现对关系数据库(MySQL)中数据的操作。Model
类与数据库表映射,Model
对象与数据库中的行映射,对象的属性与表中的字段映射。
用Python实现基本功能的ORM
首先定义Field
类,代表DB中tabale的每一个字段,对象初始化的时候需要定义的属性有,字段名称,字段数据类型,是否为主键,是否可为空,字段默认值,是否可更改等字段属性
class Field(object):
def __init__(self, **kw):
self.name = kw.get('name', None)
self._default = kw.get('default', None)
self.primary_key = kw.get('primary_key', False)
self.nullable = kw.get('nullable', True)
self.updateable = kw.get('updateable', True)
self.insertable = kw.get('insertable', True)
self.datatype = kw.get('datatype', None)
self.auto_increment = kw.get('increment', False)
Field
是所有其它Field
的父类,通过Field
可派生出不同数据类型的子类,如:
class StringField(Field):
def __init__(self, **kw):
if not 'default' in kw:
kw['default'] = ''
if not 'datatype' in kw:
kw['datatype'] = 'varchar(255)'
super(StringField, self).__init__(**kw)
这里定义了一个字符串类型的子类。那么如何来定义一个表呢。想像以下,一个类映射DB中的表,类的实例映射表中的一行数据。
class User(Mode):
__table__ = 'user'
id = IntegerField(primary_key=True)
name = StringField()
# 直接通过类方法来查询
user = User.get('123')
# 创建实例:
user = User(id=123, name='Michael')
# 存入数据库:
user.insert()
这里定义了一个user
表有2个字段,然后就可用操作了,通过类方法SELECT
查询,实例方法INSERT UPDATE DELETE
。
要实现ORM需要定义一个Mode
类,所有的表映射都是Mode
的子类。表的实例中一个字段的值与字段名称是key-value的关系,所以dict
可用作为Mode
的父类。
class Mode(dict):
__metaclass__ = ModelMetaClass
def __init__(self, *args, **kw):
super(Mode, self).__init__(*args, **kw)
元类ModelMetaClass
所做的事情就是拦截Mode
类的创建,获取所有的类属性,如果发现类属性为Field
的子类,则建立映射关系。
class ModelMetaClass(type):
def __new__(cls, name, bases, attrs):
mapping = {}
for k, v in attrs.iteritems():
if instance(v, Field):
mapping[k] = v
for k in mapping.keys()
attrs.pop(k)
attrs['__mapping__'] = mapping
super(ModelMetaClass, cls).__new__(cls, name, bases, attrs)
这样就建立了映射关系,然后实现Mode类的类方法与实例方法。就能操作数据库了。