跟着廖大大学习的过程中,遇到的许多问题都得以解决,但是在实战编写ORM时给我的感觉就是知识出现了断层,看来看去不知道哪里有问题,又感觉都是问题,不得已去git上参考着源码一行一行的敲,这样的方式给了我很多的灵感,所以将此记录分享,希望能够帮助到各位博友。
经过学习,得出结论,我的断层在面向对象高级编程中使用元类一篇:
此篇廖大大说:metaclass是Python面向对象里最难理解,也是最难使用的魔术代码。正常情况下,你
不会碰到需要使用metaclass的情况,所以,以下内容看不懂也没关系,因为基本上你不会用到。
所以当时并没有仔细的去看,理解metaclass的概念在此实战中帮助很大,建议先大概了解基础概念后对照实际代码具体理解。
下图可以帮助理解,当一个类使用动态创建时基本的运行过程:
orm数据库连接文件
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'orm数据库连接'
__author__ = 'BWone'
import aiomysql, logging
from boto.compat import StandardError
from socks import log
logging.basicConfig(level=logging.INFO)
def log(sql, args=()):
' 打印sql '
logging.info('SQL: %s' % sql)
async def create_pool(loop, **kw):
' 创建全局的连接池 '
logging.info('create database connection pool...')
global __pool
# kw.get()的方式直接定义,kw['']的方式需要传入相应的属性
__pool = await aiomysql.create_pool(
host = kw.get('host', 'localhost'), # 主机号
port = kw.get('port', 3306), # 端口号
user = kw['user'], # 用户名
password = kw['password'], # 密码
db = kw['db'], # 数据库
charset = kw.get('charset', 'utf8'), # 编码格式
autocommit = kw.get('autocommit', True), # 自动提交
maxsize = kw.get('maxsize', 10), # 最大连接数量
minsize=kw.get('minsize', 10), # 最小连接数量
loop = loop
)
async def select(sql, args, size=None):
' 执行Select '
log(sql, args)
global __pool
async with __pool.get() as conn:
# aiomysql.DictCursor将结果作为字典返回
async with conn.cursor(aiomysql.DictCursor) as cur:
# 执行语句,第一个参数传入sql语句并将语句中的?替换为%s,第二个语句传入参数
await cur.execute(sql.replace('?', '%s'), args or ())
# 如果size有值根据值获取行数,没有值时默认为None查询所有数据
if size:
# 指定一次要获取的行数
rs = await cur.fetchmany(size)
else:
# 返回查询结果集的所有行(查到的所有数据)
rs = await cur.fetchall()
logging.info('rows returned: %s' % len(rs))
return rs
async def execute(sql, args, autocommit=True):
' 执行Insert, Update, Delete '
log(sql)
async with __pool.get() as conn:
# 执行改变数据的语句时判断是否自动提交,not True相当于False
if not autocommit:
await conn.begin()
try:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute(sql.replace('?', '%s'), args)
affected = cur.rowcount
if not autocommit:
await conn.commit()
except BaseException as e:
if not autocommit:
await conn.rollback()
raise
return affected
def create_args_string(num):
' 根据输入的数字创建参数个数,例如:输入3返回 ?, ?, ? '
L = []