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运行报错UnicodeDecodeError的解决方法
Jun 07 Python
Python3处理HTTP请求的实例
May 10 Python
python+splinter实现12306网站刷票并自动购票流程
Sep 25 Python
Django model序列化为json的方法示例
Oct 16 Python
20行python代码实现人脸识别
May 05 Python
selenium 安装与chromedriver安装的方法步骤
Jun 12 Python
Python函数式编程指南:对生成器全面讲解
Nov 19 Python
基于python 等频分箱qcut问题的解决
Mar 03 Python
Python3 ffmpeg视频转换工具使用方法解析
Aug 10 Python
浅谈盘点5种基于Python生成的个性化语音方法
Feb 05 Python
Pytorch - TORCH.NN.INIT 参数初始化的操作
Feb 27 Python
浅谈Python数学建模之整数规划
Jun 23 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
操作Oracle的php类
2006/10/09 PHP
php中cookie的作用域
2008/03/27 PHP
php 批量替换程序的具体实现代码
2013/10/04 PHP
php 生成短网址原理及代码
2014/01/23 PHP
PHP 爬取网页的主要方法
2018/07/13 PHP
javascript 跨浏览器开发经验总结(五) js 事件
2010/05/19 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
extjs两个tbar问题探讨
2013/08/08 Javascript
Jquery api 速查表分享
2015/01/12 Javascript
js改变style样式和css样式的简单实例
2016/06/28 Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
2016/09/20 Javascript
VUE开发一个图片轮播的组件示例代码
2017/03/06 Javascript
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
jquery实现的分页显示功能示例
2019/08/23 jQuery
[02:23]2016国际邀请赛中国区预选赛wings晋级之路
2016/06/29 DOTA
Python中自定义函数的教程
2015/04/27 Python
Python给你的头像加上圣诞帽
2018/01/04 Python
浅谈Pandas 排序之后索引的问题
2018/06/07 Python
python学生管理系统
2019/01/30 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
Flask框架钩子函数功能与用法分析
2019/08/02 Python
Python编写万花尺图案实例
2021/01/03 Python
Python爬虫制作翻译程序的示例代码
2021/02/22 Python
CSS3中各种颜色属性的使用教程
2016/05/17 HTML / CSS
HTML5 拖拽批量上传文件的示例代码
2018/03/28 HTML / CSS
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
super关键字的用法
2012/04/10 面试题
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
2012/05/30 面试题
测绘工程专业个人自我评价
2013/12/01 职场文书
春风行动实施方案
2014/03/28 职场文书
户外宣传策划方案
2014/05/25 职场文书
青春雷锋观后感
2015/06/10 职场文书
2019年12月24日平安夜祝福语集锦
2019/12/24 职场文书