python网络编程学习笔记(九):数据库客户端 DB-API


Posted in Python onJune 09, 2014

一、DB-API概述

      python支持很多不同的数据库。由于不同的卖家服务器导致和数据库通信的网络协议各有不同。在python的早期版本中,每一种数据库都带有自己的python模块,所有这些模块以不同的方式工作,并提供不同的函数。这种方法不便于编写能够在多种数据库服务器类型中运行的代码,于是DB-API库函数产生。在DB-API中,所有连接数据库的模块即便是底层网络协议不同,也会提供一个共同的接口。这一点和JAVA中的JDBC和ODBC类似。
      DB-API下载地址:http://wiki.python.org/moin/DatabaseProgramming,目前版本是2.0,支持数据库包括IBM DB2、Firebird (and Interbase) 、Informix、Ingres、MySQL、Oracle 、PostgreSQL 、SAP DB (also known as "MaxDB") 、Microsoft SQL Server 、Sybase 等。

二、数据库连接

1、PostgreSQL

      有几个模块可以完成python与PostgreSQL的联接,这里主要介绍使用psycopg。
下载地址是:http://initd.org/psycopg/download/。如果没有PostgreSQL,可以从以下地址下载:http://www.postgresql.org/。(关于PostgreSQL的安装等更加详细的介绍,可以见http://wenku.baidu.com/view/8e32d10c6c85ec3a87c2c500.html。)连接PostgreSQL数据库:

import psycopg2
print "connecting to test"##test为数据库名
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"

2、MySQL

对于MySQL,python的接口是已知的MySQLdb或者MySQL-Python,下载地址:http://sourceforge.net/projects/mysql-python/。与PostgreSQL不同的是,MySQLdb connect()函数可以带各种参数,具体如下:

参数 说明
user 用户名,默认为当前登录用户。
passwd 用户密码,没有默认的。
db 连接的数据库名。
host 数据库主机名。
port TCP端口,默认是3306。

举例,连接test数据库:
import MySQLdb
print "connecting..."
dbh=MySQLdb.connect(db="test")
print "connection successful."
dbh.close()

三、简单操作(以PostgreSQL为例)

这里以PostgreSQL为例介绍创建表、查询表等操作。例子中数据库名为test,用户名为postgres,输入一个表名,向表中插入数据并进行查询。具体如下,已进行了注示:

import psycopg2
print "connecting to test"
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"
cur=dbh.cursor()#建立一个cursor对象,返回数据为字典形式
a=raw_input('table list:')#输入表名
cur.execute("CREATE TABLE %s(myid integer UNIQUE,filename varchar(255))" %a)#生成表,包含一个字段filename
b=1c='201210310540'
cur.execute("INSERT INTO %s VALUES (%d,%s)"%(a,b,c))#向表中插入记录b,c
cur.execute("SELECT * FROM %s " %a)#查询表中内容
rows=cur.fetchall()#获得结果集中的所有行
for row in rows:
    print row
dbh.commit()#以上对数据库的操作事务生效
dbh.close()

1、事务

多数数据库支持事务,事务可以将多条对数据库的改动放在一条命令中。在上面的例子中,当未曾执行commit()命令时,以上对数据库的操作均不会生效。另外还有一个函数rollback(),这个函数可以有效的放弃上一次执行commit()或者rollback()之后的改动。这个函数在发现错误,并想放弃已经发出的事务时,非常有效。对于不支持事务的数据库,改变会立刻执行,commit()什么也不做,但rollback()会报错。

2、效率

执行事件的性能很大程序上取决于不同的服务器,一般来说,在每个单独的命令后都提交是更新数据库最慢的方法,但如果一次提交很大数据又会使服务器产生buffer溢出。因此,应该合理处理提交的数量。

四、参数风格
在上面的例子中,使用了printf()一样的类型格式。但实际上,在DB-API中,不同的数据库所支持的参数风络不同,必须选择合适的方法,否则程序不会执行。下面的方法,可以知道当前所支持的类型格式。

>>> import psycopg2
>>> print psycopg2.paramstyle

pyformat这一结果可以看出,当前支持pyformat格式。

针对DB-API说明书,以使用频度由小变大的顺序介绍:

qmark 表示question-mark风格。指令字符串中的数据的每一位都被用一个问号替换,参数以list或tuple的形式给出。例如:INSERT INTO ch14 VALUES (?, ?)。
format 使用和printf()一样的类型格式,不支持对于指定参数Python的扩展名。它带一个list或tuple来转换。例如:INSERT INTO ch14 VALUES(%d, %s)
numeric 表示numeric风格。指令字符串中的数据的每一位都被一个后面是数字的冒号替换(数字以1开始),参数以list或tuple的形式给出。例如:INSERT INTO ch14 VALUES(:1, :2)
named 表示named风格。和numeric类似,但是在冒号后面用名称取代数字。带一个dictionary用来转换。例如:INSERT INTO ch14 VALUES(:number, :text)
pyformat 支持Python风格的参数,带dictionary用来转换。例如:INSERT INTO ch14 VALUES(%(number)d, %(text)s)。

五、重复指令
1、execute和executemany()

例子:

将下面的数据插入到test数据库中:

12 Twelve
13 Thirteen
14 Fourteen
15 Fifteen

(1)execute一条条插入

cur.execute("INSERT INTO test VALUES (12, 'Twelve')")
cur.execute("INSERT INTO test VALUES (13, 'Thirteen')")
cur.execute("INSERT INTO test VALUES (14, 'Fourteen')")
cur.execute("INSERT INTO test VALUES (15, 'Fifteen')")

这种方法过于低效。

(2)executemany()函数带一个指令和一列指令运行的记录。列表上的每条记录要么是一个list,要么是一个dictionary。

import psycopg2
print "connecting to test"
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"
cur=dbh.cursor()
rows = ({'num': 0, 'text': 'Zero'},
         {'num': 1, 'text': 'Item One'},
         {'num': 2, 'text': 'Item Two'},
         {'num': 3, 'text': 'Three'})
cur.executemany("INSERT INTO test VALUES (%(num)d, %(text)s)", rows)
dbh.commit()
dbh.close()

executemany()主要的缺点是,在需要执行指令前把所有的记录放在内存中。如果数据大的话,这就是一个问题,它会占有系统的所有内存资源。如果executemany()不能满足需要,那么除了execute()之外,还是有可能取得性能优化的。根据DB-API说明,当execute()被周期性调用时,数据库后端可以执行优化。但是它的第一个参数必须指向同一个对象,而不是一个含有相同值的字符串,即在内存中的同一个字符串对象。和executemany()一样,这样并不能保证优化,并且也不能期望execute()运行得比executemany()快。但是如果不能使用executemany(),这就是一个最好的选择。

六、fetchall、fetchmany、fetchone获取数据

fetchall(self):接收全部的返回结果行。

fetchmany(self, size=None):接收size条返回结果行.如果size的值大于返回的结果行的数量,则会返回cursor.arraysize条数据。

fetchone(self):返回一条结果行。

七、获取metadata(元数据)

元数据的英文名称是“Metadata",它是“关于数据的数据”。如在上面的例子中,Metadata的结果为:

Column(name='id', type_code=23, display_size=None, internal_size=4, precision=None, scale=None, null_ok=None)
Column(name='filename', type_code=1043, display_size=None, internal_size=255, precision=None, scale=None, null_ok=None)

import psycopg2
print "connecting to bbstime"
dbh=psycopg2.connect('dbname=bbstime user=postgres')
print "connection successful"
cur=dbh.cursor()
cur.execute("SELECT * FROM asd")
for column in cur.description:
    print column
dbh.close()

八、计算行数
方法有两种,一种是用len(),一种是用rowcount。

import psycopg2
print "connecting to bbstime"
dbh=psycopg2.connect('dbname=bbstime user=postgres')
print "connection successful"
cur=dbh.cursor()
cur.execute("SELECT * FROM test")
rows=cur.fetchall()
print len(rows)#利用len来计算行数
print "rows:",cur.rowcount#利用rowcount来计算行数 
dbh.close()
Python 相关文章推荐
python使用in操作符时元组和数组的区别分析
May 19 Python
Django使用Celery异步任务队列的使用
Mar 13 Python
Django使用HttpResponse返回图片并显示的方法
May 22 Python
python用post访问restful服务接口的方法
Dec 07 Python
Python实现的逻辑回归算法示例【附测试csv文件下载】
Dec 28 Python
python数据归一化及三种方法详解
Aug 06 Python
python使用matplotlib绘制雷达图
Oct 18 Python
python如何判断IP地址合法性
Apr 05 Python
python支持多继承吗
Jun 19 Python
Django Session和Cookie分别实现记住用户登录状态操作
Jul 02 Python
Python Selenium模块安装使用教程详解
Jul 09 Python
python 写一个水果忍者游戏
Jan 13 Python
python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
Jun 09 #Python
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
Jun 09 #Python
python网络编程学习笔记(六):Web客户端访问
Jun 09 #Python
python网络编程学习笔记(五):socket的一些补充
Jun 09 #Python
python网络编程学习笔记(四):域名系统
Jun 09 #Python
python网络编程学习笔记(三):socket网络服务器
Jun 09 #Python
python网络编程学习笔记(二):socket建立网络客户端
Jun 09 #Python
You might like
redis 队列操作的例子(php)
2012/04/12 PHP
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
js单例模式的两种方案
2013/10/22 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
jQuery+css实现的换页标签栏效果
2016/01/27 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
Vue内容分发slot(全面解析)
2017/08/19 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
2017/10/09 Javascript
微信 jssdk 签名错误invalid signature的解决方法
2019/01/14 Javascript
vue实现日历备忘录功能
2020/09/24 Javascript
vue-socket.io跨域问题有效解决方法
2020/02/11 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
JS实现电脑虚拟键盘的操作
2020/06/24 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
Python合并两个字典的常用方法与效率比较
2015/06/17 Python
完美解决Python 2.7不能正常使用pip install的问题
2018/06/12 Python
tensorflow: variable的值与variable.read_value()的值区别详解
2018/07/30 Python
python简单鼠标自动点击某区域的实例
2019/06/25 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
2020/02/17 Python
Python argparse模块使用方法解析
2020/02/20 Python
Jupyter Notebook打开任意文件夹操作
2020/04/14 Python
完美解决jupyter由于无法import新包的问题
2020/05/26 Python
Django REST 异常处理详解
2020/07/15 Python
python实现最短路径的实例方法
2020/07/19 Python
实现Python3数组旋转的3种算法实例
2020/09/16 Python
解决python3中os.popen()出错的问题
2020/11/19 Python
Python抖音快手代码舞(字符舞)的实现方法
2021/02/07 Python
英国网络托管和域名领导者:Web Hosting UK
2017/10/15 全球购物
中专生职业生涯规划书范文
2014/01/10 职场文书
《曹刿论战》教学反思
2014/03/02 职场文书
生产操作工岗位职责
2014/09/16 职场文书
优秀班主任主要事迹材料
2014/12/16 职场文书
爱心捐书倡议书
2015/04/27 职场文书
保险公司2016开门红口号集锦
2015/12/24 职场文书
Python函数对象与闭包函数
2022/04/13 Python