D3是关于mysql的
1、import aiomysql错误
2、什么是ORM,为什么要用ORM
3、aiomysql相关的介绍
4、元类相关的介绍,type、metaclass、type.new()
先是导入import aiomysql时出现错误,ImportError: cannot import name '_scramble'。
网上查了之后说是版本问题,直接安装aiomysql时,装的pymysql是0.9.0版本,似乎有问题。于是要改为装0.8.0。
运行CMD,直接输入pip,可以查看pip支持的指令。
先卸载已经安装的pymysql, pip uninstall pymysql
然后安装指定的版本,pip install pymysql==0.8.0
编写ORM。
为什么要用ORM,ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。
一个类对应一个表即:举例 定义一个class User(xxxx): 类,来对应数据库表User。类中的定义的方法就可以是针对这个数据进行的增删改查操作。
例如:
class User(Model): #对User表的定义
# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password')
# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
# 保存到数据库:
u.save()
#可见如果ORM建出来后,对表的操作非常简单。
其中,父类Model
和属性类型StringField
、IntegerField
是由ORM框架提供的(在之后的教程会提到相关的内容),剩下的魔术方法比如save()
全部由metaclass自动完成。虽然metaclass的编写会比较复杂,但ORM的使用者用起来却异常简单。
对这块的理解,是廖雪峰“使用元类”的教程里有具体介绍。https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000
对这块的理解一定要把面向对象的教程吃透。
创建连接池
我们需要创建一个全局的连接池,每个HTTP请求都可以从连接池中直接获取数据库连接。使用连接池的好处是不必频繁地打开和关闭数据库连接,而是能复用就尽量复用。
@asyncio.coroutine
def create_pool(loop, **kw):
logging.info('create database connection pool...')
global __pool
__pool = yield from aiomysql.create_pool( #创建pool,读取入参kw里的信息去创建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', 1),
loop=loop
)
kw是个关键字参数,为dict类型。要得到kw的值,用了get语句。kw.get('port',3306),如果‘port’不存在,则赋值为3306。
Select
要执行SELECT语句,我们用select
函数执行,需要传入SQL语句和SQL参数:
@asyncio.coroutine
def select(sql, args, size=None): #三个入参
log(sql, args)
global __pool
with (yield from __pool) as conn: #异步打开__pool,并赋值给conn
cur = yield from conn.cursor(aiomysql.DictCursor) #建立一个dict类型的游标
yield from cur.execute(sql.replace('?', '%s'), args or ()) #执行sql语句,在执行前需要将通配符做下替换,将?换成%s。args就是%s的参数了。
if size:
rs = yield from cur.fetchmany(size)
else:
rs = yield from cur.fetchall()
yield from cur.close()
logging.info('rows returned: %s' % len(rs))
cursor,正常是返回一个元组(tuple)类型的的游标。但也可以加参数,将游标变成指定类型的。DictCursor是一个类,用于创建dict类型的Cursor。这里将类的名称作为函数入参了。
cur = yield from conn.cursor(aiomysql.DictCursor) 将类名作为函数入参的例子:用类名作为