参悟python元类(又称metaclass)系列实战(四)
写在前面
在上一章节参悟python元类(又称metaclass)系列实战(三)完成了
users类
和users表
的字段映射;在继续丰富
users类
的操作之前, 我们花一章来完成mysql的链接;有误的地方恳请大神指正下。
创建全局连接池, 以求避免频繁地打开和关闭数据库连接
因为查询耗时, 计划引入异步, 即
async/await
(不懂没关系, 就当是普通代码, 只是调用方式特别而已)$ pip3 install aiomysql # 通过pip安装
创建
Mysql类
, 定义静态方法createPool
import aiomysql
class Mysql:
@staticmethod
async def createPool():
"""连接池由全局变量__pool存储,缺省情况下将编码设置为utf8,自动提交事务"""
try:
global __pool
__pool = await aiomysql.create_pool(
host="localhost", # mysql服务器地址
port=3306, # mysql监听端口
user="root", # mysql用户名
password="passwd", # mysql密码
db="ormdemo", # mysql实例名(database)
charset="utf8", # 编码设置
autocommit=True, # 自动提交insert/update/delete
maxsize=10, # 连接池上限
minsize=1 # 连接池下限
)
print("创建成功")
except Exception as e:
print(f"连接 mysql 出错:{e}")
# 测试代码
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(Mysql.createPool())
给
Mysql类
新增静态方法select
、execute
@staticmethod
async def select(sql, args, size=None):
"""传入SQL语句和SQL参数
@sql : sql语句
@args: 条件值列表
@size: 查询的结果集大小
"""
print(f"{sql} ==> {args}")
# 使用with上下文管理器, 自动执行close
async with __pool.acquire() as conn:
# acquire: 从空闲池获得连接。如果需要,并且池的大小小于maxsize,则创建新连接。
async with conn.cursor(aiomysql.DictCursor) as cur:
# cursor: 连接的游标
# DictCursor: 作为字典返回结果的游标
await cur.execute(sql.replace("?", "%s"), args or ())
# sql.replace("?", "%s"): "SELECT * FROM users WHERE uid=?".replace("?", "%s")
# args or (): "SELECT * FROM users WHERE uid=%s" % (101,)
if size:
rs = await cur.fetchmany(size)
else:
rs = await cur.fetchall()
print(f"rows returned: {len(rs)}")
return rs
@staticmethod
async def execute(sql, args, autocommit=True):
"""
INSERT、UPDATE、DELETE操作,可以通用的execute函数,
因为这3种SQL的执行都需要相同的参数, 返回一个整数表示影响的行数
"""
print(f"{sql} ==> {args}")
async with __pool.acquire() as conn:
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 Exception as e:
if not autocommit:
await conn.rollback() # 回滚更改
raise Exception(e)
return affected
测试下select
if __name__ == "__main__": import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(Mysql.createPool())
rs = loop.run_until_complete(Mysql.select("select uid, name from users where uid=?", [101]))
print(rs)
- 控制台输出
创建成功select * from users where uid=? ==> [101]
rows returned: 1
[{"uid": 101, "name": "z417"}]
总结
定义了
Mysql类
, 其中有3个静态方法引入了异步, 调用方式共分两步
以上是 参悟python元类(又称metaclass)系列实战(四) 的全部内容, 来源链接: utcz.com/z/537852.html