Python3廖雪峰实战项目:重难点ORM

Python3学到现在,进入了实战项目阶段:搭建个人博客。
day3的内容,我消化了好几天,今天大致清晰了,完成了编码和粗略测试,这里做个记录。

1. 难点一:理解ORM是关键

ORM:object relationship model 对象关系映射

我的理解:在一个项目里面,需要对数据库进行大量的操作(一个项目,说白了,就是界面+对数据库的增删查改),在不同的地方重复操作数据库,即多次重复与数据库的交互,这样,不仅造成代码冗余,而且导致后期的修改维护不方便。面对这种情况,orm的概念应运而生,即将一个数据库表映射成一个类,简单说就是将与数据库的多种交互操作,封装成一个类,类里面包含之前的增删查改等操作方法。

2. 难点二:理解元类metaclass

metaclass(元类),继承自type,通俗来说是,用来创建类的类工厂,当一个类继承了某个元类,会调用元类中的方法初始化、创建类。
ModelMetaclass:类的元类,主要是为了将一个数据库表映射成类做准备工作。

3. 难点三:注意一步异步,处处异步

为了处理大量用户的请求,采用协程(只有一个线程,控制协程的切换),协程是异步的,所以不能采用一般的IO处理(速度太慢,严重影响协程),故采用面向mysql的异步Io:aiomysql。

其他细节都在下面代码的注释里,当然包括网友们的理解和自己的一些理解,详情见下方代码。

#orm.py

#coding:utf-8
#day3:ORM 对象关系映射:通俗说就是将一个数据库表映射为一个类

import sys,random
import asyncio
#一步异步,处处使用异步
import aiomysql
import logging
logging.basicConfig(level=logging.INFO)#日志记录

#日志打印函数:打印出使用的sql语句
def log(sql,args=()):
    logging.info('SQL:%s'%sql)

#异步协程:创建数据库连接池
@asyncio.coroutine
def create_pool(loop,**kw):
    logging.info('start creating database connection pool')
    #全局私有变量,尽内部可以访问
    global __pool 
    #yield from 调用协程函数并返回结果
    __pool = yield from aiomysql.create_pool(
        #kw.get(key,default):通过key在kw中查找对应的value,如果没有则返回默认值default
        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',1),
        loop = loop
        )

#协程:销毁所有的数据库连接池
async def destory_pool():
    global  __pool
    if __pool is not None:
        __pool.close()
        await __pool.wait_closed()

#协程:面向sql的查询操作:size指定返回的查询结果数
@asyncio.coroutine 
def select(sql,args,size=None):
    log(sql,args)
    global __pool
    #yield from从连接池返回一个连接
    with (yield from __pool) as conn:
        #查询需要返回查询的结果,按照dict返回,所以游标cursor中传入了参数aiomysql.DictCursor
        cur = yield from conn.cursor(aiomysql.DictCursor)
        #执行sql语句前,先将sql语句中的占位符?换成mysql中采用的占位符%s
        yield from cur.execute(sql.replace('?','%s'),args)
        if size:
            rs = yield from cur.fetchmany(size)
        else:
            rs = yield from cur.fetchall()
        yield from cur.close()
        logging.info('%s rows have returned' % len(rs))
    return rs

#将面向mysql的增insert、删delete、改update封装成一个协程
#语句操作参数一样,直接封装成一个通用的执行函数
#返回受影响的行数
@asyncio.coroutine
def execute(sql,args,autocommit = True):
    log(sql,args)
    global __pool
    with (
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值