Python下ORM的一个设计举例

ORM是对象-关系管理器,是对数据库进行操作的API接口。选择MySQL作为网站的后台数据库;执行SQL语句进行操作,并将常用的SELECT、INSERT等语句进行函数封装;在异步框架的基础上,采用aiomysql作为数据库的异步IO驱动;将数据库中表的操作,映射成一个类的操作,也就是数据库表的一行映射成一个对象(ORM)。整个ORM也是异步操作。
预备知识:Python协程和异步IO(yield from的使用)、SQL数据库操作、元类、面向对象知识、Python语法
思路
  
如何定义一个user类,这个类和数据库中的表User构成映射关系,二者应该关联起来,user可以操作表User    
  通过Field类将user类的属性映射到User表的列中,其中每一列的字段又有自己的一些属性,包括数据类型,列名,主键和默认值

python的版本是Python 3.5.2

orm.py
# -*-coding:utf-8 -*-
import asyncio, logging
import aiomysql
 
# 打印SQL查询语句
def log(sql, args=()):
    logging.info('SQL: %s'%(sql))
 
# 创建一个全局的连接池,每个HTTP请求都从池中获得数据库连接
@asyncio.coroutine
def create_pool(loop, **kw):
    logging.info('create database connection pool...')
    # 全局变量__pool用于存储整个连接池
    global __pool
    __pool = yield from aiomysql.create_pool(
            # **kw参数可以包含所有连接需要用到的关键字参数
            # 默认本机IP
            host = kw.get('host','localhost'),
            user = kw['user'],
            password = kw['password'],
            db = kw['db'],
            port = kw.get('port',3306),
            charset = kw.get('charset','utf8'),
            autocommit = kw.get('autocommit', True),
            # 默认最大连接数为10
            maxsize = kw.get('maxsize', 10),
            minsize = kw.get('minisize', 1),            
            # 接收一个event_loop实例
            loop = loop
            )
 
# 封装SQL SELECT语句为select函数
def select(sql, args, size=None):
    log(sql, args)
    global __pool    
    # -*- yield from 将会调用一个子协程,并直接返回调用的结果
    # yield from从连接池中返回一个连接
    with(yield from __pool) as conn:
        # DictCursor is a cursor which returns results as a dictionary
        cur = yield from conn.cursor(aiomysql.DictCursor)        
        # 执行SQL语句
        # SQL语句的占位符为?,MySQL的占位符为%s
        yield from cur.execute(sql.replace('?','%s'), args or ())            
        # 根据指定返回的size,返回查询的结果
        ifsize:
            # 返回size条查询结果
            rs = fetchmany(size)
        else:
            # 返回所有查询结果
            rs = fetchall()
        yield from cur.close()
        logging.info('rows return: %s'%(len(rs)))
        returnrs
 
# 封装INSERT, UPDATE, DELETE
# 语句操作参数一样,所以定义一个通用的执行函数
# 返回操作影响的行号
@asyncio.coroutine
def execute(sql, args):
    log(sql, args)
    global __pool
    with(yield from __pool) as conn:
        try:
            # execute类型的SQL操作返回的结果只有行号,所以不需要用DictCursor
            cur = yield from conn.cursor()
            cur.execute(sql.replace('?','%s'), args)
            affectedLine = cur.rowcount
            yield from cur.close()
        except BaseException as e:
            raise
        returnaffectedLine
 
# 根据输入的参数生成占位符列表
def create_args_string(num):
    L = []
    fornin range(num):
        L.append('?')    
    # 以','为分隔符,将列表合成字符串
    return(','.join(L))
 
# 定义Field类,负责保存(数据库)表的字段名和字段类型
class Field(object):
    # 表的字段包含名字、类型、是否为表的主键和默认值
    def __init__(self, name, column_type, primary_key,default):
        self.name = name
        self.column_type = column_type
        self.primary_key = primary_key
        self.default=default
     
    # 当打印(数据库)表时,输出(数据库)表的信息:类名,字段类型和名字
    def __str__(self):
        return('
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值