在 Python 中,数据库是通过适配器 (Adaptor) 来连接访问数据库的,适配器通常与数据库客户端接口 (通常为 C 语言编写) 想连接,而不同的适配器都会尽量满足相同的 DB-API 标准。
为了保证不同数据库的数据库接口能够通用于适配器,以减少使用不同数据库接口是需要对代码进行大幅改动,Python 的 DB-SIG(数据库特殊兴趣小组) 制定了 DB-API 的标准,该 API 为不同的关系数据库提供了一致的接口,使得使用不同数据库的代码间移植变得更加简单。数据库接口目前的版本为 DB-API(2.0),可前往 Python 官网查看 最新版本 。
通用标准 / General Standard
对于任意的数据库适配器 db,需要提供至少以下几项通用标准,以保证可移植性。
1 属性 / Attribute
1.1 apilevel 属性
属性调用: al = db.apilevel
属性功能: 返回当前适配器支持的 DB-API 版本
属性参数: al
al: str 类型,目前支持 "1.0" 和 "2.0" 两种,如果该适配器未指定,则假定为 "1.0"
1.2 threadsafety 属性
属性调用: tsf = db.threadsafety
属性功能: 返回当前适配器支持的线程安全等级
属性参数: tsf
tsf: int 类型,线程安全等级
threadsafety |
Meaning |
0 |
Threads may not share the module. |
1 |
Threads may share the module, but not connections. |
2 |
Threads may share the module and connections. |
3 |
Threads may share the module, connections and cursors. |
1.3 paramstyle 属性
属性调用: psy = db.paramstyle
属性功能: 返回当前适配器支持的参数风格
属性参数: psy
psy: str 类型,参数风格的说明
paramstyle |
Meaning |
qmark |
Question mark style, e.g. ...WHERE name= |
numeric |
Numeric, positional style, e.g. ...WHERE name=:1 |
named |
Named style, e.g. ...WHERE name=:name |
format |
ANSI C printf format codes, e.g. ...WHERE name=%s |
pyformat |
Python extended format codes, e.g. ...WHERE name=%(name)s |
2 函数 / Function
2.1 connect () 函数
函数调用: cnx = db.connect/Connection/Connect(*args, **kwargs)
函数功能: 生成一个数据库的连接对象
传入参数: args, kwargs
host: str 类型,连接的主机地址,未传入或'localhost'都将连接本地数据库
user: str 类型,登入数据库的用户名
password/passwd: str 类型,登录数据库的密码
database/db: str 类型,使用的数据库 schema 名称
返回参数: cnx
cnx: obj 类型,一个数据库连接实例
3 类 / Class
3.1 Connection 类
类实例化:cnx = db.connect/Connection/Connect(*args, **kwargs)
类的功能: 用于联系数据库 API 的连接对象
传入参数: args, kwargs
host: str 类型,连接的主机地址,未传入或'localhost'都将连接本地数据库
user: str 类型,登入数据库的用户名
password/passwd: str 类型,登录数据库的密码
database/db: str 类型,使用的数据库 schema 名称
返回参数: cnx
cnx: obj 类型,一个数据库连接实例
3.1.1 close() 方法
函数调用: cnx.close()
函数功能: 关闭数据库连接
传入参数: 无
返回参数: 无
3.1.2 commit() 方法
函数调用: cnx.commit()
函数功能: 提交当前事务,通常当命令具有执行修改等性质的时候需要此函数完成确认
传入参数: 无
返回参数: 无
3.1.3 rollback() 方法
函数调用: cnx.rollback()
函数功能: 取消当前事务
传入参数: 无
返回参数: 无
3.1.4 cursor() 方法
函数调用: cur = cnx.cursor()
函数功能: 使用该连接对象创建返回一个游标对象
传入参数: 无
返回参数: cur
cur: obj 类型,游标对象的实例,可以通过游标进行操作数据库
3.2 Cursor 类
类实例化:cur = cnx.cursor()
类的功能: 一个用于操作数据库的游标对象
传入参数: args, kwargs
host: str 类型,连接的主机地址,未传入或'localhost'都将连接本地数据库
user: str 类型,登入数据库的用户名
password/passwd: str 类型,登录数据库的密码
database/db: str 类型,使用的数据库 schema 名称
返回参数: cnx
cnx: obj 类型,一个数据库连接实例
3.2.1 arraysize 属性
属性调用: as = cur.arraysize
属性功能: 表示使用 fetchmany() 方法时,一次性取出的结果行数,默认为 1
属性参数: as
as: int 类型,一次性 fetch 的行数
3.2.2 connection 属性
属性调用: cnx = cur.connection
属性功能: 返回生成该游标的 connection 实例
属性参数: cnx
cnx: obj 类型,生成当前游标的连接实例
3.2.3 description 属性
属性调用: dsp = cur.description
属性功能: 返回当前游标的活动状态
属性参数: dsp
dsp: tuple/NoneType 类型,一个 7 元素元组描述当前状态
3.2.4 lastrowid 属性
属性调用: rid = cur.lastrowid
属性功能: 上次修改行的 ID,不支持则返回 None
属性参数: rid
rid: int/NoneType 类型,修改的行 ID
3.2.5 rowcount 属性
属性调用: roc = cur.rowcount
属性功能: 上次 execute*() 修改行所影响的行数
属性参数: roc
roc: int 类型,修改影响的行数
3.2.6 close() 方法函数调用: cur.close()
函数功能: 关闭游标
传入参数: 无
返回参数: 无
3.2.7 execute() 方法
函数调用: [r =] cur.execute(query, args=None)
函数功能: 执行数据库命令
传入参数: query, args
query: str 类型,执行的 SQL 命令行
args: sequence/mapping 类型,query 使用的参数
返回参数: r
r: int 类型,执行所影响的行数
3.2.8 executemany() 方法
函数调用: [r =] cur.executemany(query, args)
函数功能: 执行多条数据库命令,类似 execute() 和 map() 的结合
传入参数: query, args
query: str 类型,执行的 SQL 命令行
args: sequence/mapping 类型,query 使用的参数
返回参数: r
r: int 类型,执行所影响的行数
3.2.9 fetchone() 方法
函数调用: r = cur.fetchone()
函数功能: 获取查询结果的下一行
传入参数: 无
返回参数: r
r: tuple 类型,查询结果的下一条信息的元组
3.2.10 fetchmany() 方法
函数调用: r = cur.fetchmany(size=cursor.arraysize)
函数功能: 获取查询结果的下 n 行,默认为 arraysize 的设置值
传入参数: size
size: int 类型,查询下 n 行
返回参数: r
r: tuple 类型,查询结果的下 n 条信息的元组
3.2.11 fetchall() 方法
函数调用: r = cur.fetchall()
函数功能: 获取查询结果的所有 (剩余) 行
传入参数: 无
返回参数: r
r: tuple 类型,查询结果的所有剩余信息元组
4 补充知识 / Complement Knowledge
4.1 Cursor 与 Connection
在 MySQL 中,Connection 生成的实例利用 query 函数已经可以完成基本的 SQL 数据库操作,而 Cursor 的 execute 功能与其类似,但是引入 Cursor 可以使在不必要的时候销毁 Cursor 节省资源占用,同时无需断开连接。参考 stack overflow 链接 。
5 应用实例 / Complement Knowledge
下面的例子中将构建一个简单的通用适配器驱动,其中实现了各种适配器通用的函数方法。
- class SqlConnector():
- def __init__(self, adaptor):
- self.adaptor = adaptor
- self.result = None
- # Check Adaptor info
- print('Adaptor %s apply DB-API %s, thread safety: %d, parameter style: %s' % (adaptor.__name__, adaptor.apilevel, adaptor.threadsafety, adaptor.paramstyle))
- # Login by user name and password
- def login(self, **kwargs):
- # Create a connection obj
- self.cnx = self.adaptor.connect(**kwargs)
- def logoff(self):
- self.cnx.close()
- def query_sql(self, sql, show=True):
- # Method one: Use Connection
- '''
- self.cnx.query(sql)
- self.result = self.cnx.store_result()
- r = self.result.fetch_row(0, )
- self.cnx.commit()
- '''
- # Method two: Use Cursor
- cur = self.cnx.cursor()
- cur.execute(sql)
- r = cur.fetchall()
- self.cnx.commit()
- cur.close()
- if show:
- splt = '\n' + ((len(sql)+6)*'-')
- msg = ''.join(('\n{: ^10} | ').format(str(i)) if x.index(i) == 0 else ('{: ^10} | ').format(str(i)) for x in r for i in x)
- s = ('{:-^%d}'%(len(sql)+6)).format(sql) + msg + splt
- print(s)
- return (i for x in r for i in x)
- def exec_sql(self, sql):
- cur = self.cnx.cursor()
- cur.execute(sql)
- self.cnx.commit()
- cur.close()
- def commit(self):
- self.cnx.commit()
- if __name__ == '__main__':
- import MySQLdb
- import pymssql
- r = input('Please choose your adaptor:\n(M)MySQL\n(S)MsSQL\n')
- adaptor_list = {'M': MySQLdb, 'S': pymssql}
- c = SqlConnector(adaptor_list[r.upper()])
- # No local MSSQL server
- c.login(host='localhost', user='root', password='root')
- c.logoff()
第 1-6 行,建立适配器的类,在初始化用利用适配器的通用属性查看适配器的基本信息,包括适配器名称,使用的 DB-API 等级,线程安全等级,参数风格等。
第 8-14 行,定义登录退出函数,登录时创建连接实例,退出时关闭。第 16-36 行,定义请求函数,对于数据库的操作有两种方式实现,第一种是使用 Connection,第二种是使用 Cursor,同时对请求的结果进行显示。第 38-45 行,定义执行函数,用于执行 SQL 的命令语句,对于有修改性质的语句必须 commit 后才能在数据库端生效。第 47-55 行,最后仅对数据库进行登录退出测试,由于本地仅安装了 MYSQL,没有安装 MSSQL 的服务器,因此无法登录 MSSQL。运行结果如下参考链接
- Please choose your adaptor:
- (M)MySQL
- (S)MsSQL
- M
- Adaptor MySQLdb apply DB-API 2.0, thread safety: 1, parameter style: format
来源: http://www.bubuko.com/infodetail-2448395.html