注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

python之数据库操作(使用sqlite,安装MySQLdb)  

2011-04-07 23:51:00|  分类: Web技术-Python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

python操作数据库API

(以下信息摘至:http://anony3721.blog.163.com/blog/static/5119742010716104442536/

python的数据库模块有统一的接口标准,所以数据库操作都有统一的模式,基本上都是下面几步(假设数据库模块名为db):

1. 用db.connect创建数据库连接,假设连接对象为conn
2. 如果该数据库操作不需要返回结果,就直接用conn.execute查询,根据数据库事务隔离级别的不同,

可能修改数据库需要conn.commit
3. 如果需要返回查询结果则用conn.cursor创建游标对象cur, 通过cur.execute查询数据库,

   用cur.fetchall/cur.fetchone/cur.fetchmany返回查询结果。根据数据库事 务隔离级别的不同,

    可能修改数据库需要conn.commit
4. 关闭cur,close()

以上步骤包含两个对象

一 连接对象:包含如下方法

 conn.commit()--事务提交  conn.rollback()--事务回滚  conn.close()--关闭一个数据库连接  conn.cursor()--创建一个游标

二游标对象:包含如下属性与方法

cur.description
一个列表(name,type_code,display_size,internal_size,precision,scale,null_ok) 此属性只有在取得了数据之后才有,不然会是null值

cur.rowcount
表示返回值的行数.如果没有执行executeXXX()方法或者此模块没有实现这个方法,就会返回-1

cur.callproc(procname[,parameters])
(此为可选方法,应为不是所有的数据库都支持存储过程的)

cur.close()
关闭游标

cur.execute(operation[,parameters])
准备并执行一个数据库操作(包括查询和命令)

cur.executemany(operation,seq_of_parameters)
准备一个数据库命令,然后根据参数执行多次命令

cur.fetchone()
返回第一行的查询结果

cur.fetchmany([size=cursor.arraysize])
返回指定个多个行的值


cur.fetchall()
返回所有的查询结果

cur.arraysize
这个参数值表示fetchmany默认情况之下获取的行数

(游标说明:游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL  选择语句相关联。因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功, 该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。
        我们知道关系数据库管理系统实质是面向集合的,在Sqlite中并没有一种描述表中单一记录的表达形式,除非使用where  子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。由此可见,游标允许应用程序对查询语句select  返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。)  


在python中使用MySQL

一 Python中安装MySQLdb

如果数据库使用MySQL,那么你需要下载一个MySQLdbhttp://sourceforge.net/projects/mysql-python/,注意是win版的还是linux版的,另外还要注意python版为2.6的。

如果是win版还需要下载:libguide40.dll   和 libmmd.dll这两个文件,下载后放入到到C:\WINDOWS/system32/ 目录下。

你可以能过 bing搜索找:http://cn.bing.com/search?q=libmmd.dll++download&go=&qs=bs&form=QBRE或者直接进http://www.dlldll.com/  找到这两文件。

(注:如果你是win64的系统可以进这里下载http://www.codegood.com/archives/129,并且不需要单独dll文件了)

安装好后在import MySQLdb时,可能会出现两个错误:一个是说sets 模块找不到,另一个是说:Set 方法已被弃用了

解决这两问题可以这么做:(参考 SourceForge.net)

进入你的MYSQL安装目录,我的是:PythonDev2.6\Lib\site-packages\MySQLdb 在这个目录里找到: __init__.py 文件与converters.py文件进行如下修改:

1 把__init__.py文件里的

from sets import ImmutableSet
class DBAPISet(ImmutableSet):

注释掉,然后替换成:

class DBAPISet(frozenset):

2 在converters.py文件里:

from sets import BaseSet, Set

注释掉,然后再把:

Set: Set2Str,

这行里大“S”换成小"s",即:set: Set2Str,

好了,解决以上问题后再import MySQLdb就没有问题了。

二 链接数据库mysql,中文编码问题

这里要注意程序编码要与数据库存储数据的编码一致,在保证了程序编码与数据库编码一致后,注意以下工作:

#coding:utf-8

import MySQLdb

#链接

con = MySQLdb.connect(host='127.0.0.1',db='test',\
                     user='user',passwd='',charset='utf8'

           )
cur = con.cursor()

#设置编码方式

cur.execute('SET NAMES utf8')
n = cur.execute('select id,title from xxx  limit 20')
for i in cur.fetchall():
    print(i[1])


如果查寻(或者插入、更新)语句中有中文字符,可其转成unicode对象(unicode('xxxx','gbk'))。因为MySQLdb 类的cursors中的 execute(sql) 方法会自动判断是否需要转换成字符,其代码如下:

db = self._get_db()
charset = db.character_set_name()
if isinstance(query, unicode):
query = query.encode(charset)
if args is not None:
query = query % db.literal(args)


另外 connect(**agr) 方法的其它参数如下:

    host,连接的数据库服务器主机名,默认为本地主机(localhost)。
    user,连接数据库的用户名,默认为当前用户。
    passwd,连接密码,没有默认值。
    db,连接的数据库名,没有默认值。
    conv,将文字映射到Python类型的字典。默认为MySQLdb.converters.conversions
    cursorclass,cursor()使用的种类,默认值为MySQLdb.cursors.Cursor。
    compress,启用协议压缩功能。
    named_pipe,在windows中,与一个命名管道相连接。
    init_command,一旦连接建立,就为数据库服务器指定一条语句来运行。
    read_default_file,使用指定的MySQL配置文件。
    read_default_group,读取的默认组。
    unix_socket,在unix中,连接使用的套接字,默认使用TCP。
    port,指定数据库服务器的连接端口,默认是3306。

 

三 查寻操作

 方法与sqlite一致。


在python中使用SQLite3

不像常见的客户端/服务器结构范例,SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。这在消耗总量、延迟时间和整体简单性上有积极的作用。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。相比其它大型数据库来说,确实有些差距。但是包括事务(transaction),就是代表原子性、一致性、隔离性和持久性的(ACID),触发器(trigger)和多数的复杂查询都是支持的。另外,在于语言上绑定也是十分出色:包含了PHP,python,c/c++等等。

更多信息请参看:http://zh.wikipedia.org/wiki/SQLite

导入模块:

import sqlite3

创建数据库/打开数据库:

cx = sqlite3.connect("E:/test.db") 其实我们不需要显式的创建一个sqlite数据库,在调用connect函数的时候,指定库名称,如果指定的数据库存在就直接打开这个数据库,如果不存在就新创建一个再打开。这一点应用很好理解。

创建游标执行SQL:

cu = cx.cursor() 这样定义了一个游标。游标对象有以下的操作:

execute()--执行sql语句   executemany--执行多条sql语句   close()--关闭游标   fetchone()--从结果中取一条记录,并将游标指向下一条记录   fetchmany()--从结果中取多条记录   fetchall()--从结果中取出所有记录   scroll()--游标滚动

1,建表:
cu.execute('create table catalog (id integer primary key,pid integer,name varchar(10) UNIQUE)')

2,插入数据:
cu.execute("insert into catalog values(0, 0, 'name1')")  cu.execute("insert into catalog values(1, 0, 'hello')") 简单的插入两行数据,不过需要提醒的是,只有提交了之后,才能生效.我们使用数据库连接对象cx来进行提交commit和回滚rollback操作.
cx.commit()

3,查询:
cu.execute("select * from catalog") 要提取查询到的数据,使用游标的fetch***函数,如:
print cu.fetchall() 返回结果如下:
[(0, 0, u'name1'), (1, 0, u'hello')] 如果我们使用cu.fetchone(),则首先返回列表中的第一项,再次使用,则返回第二项,依次下去.

4,修改:
cu.execute("update catalog set name='name2' where id = 0") 

cx.commit() 注意,修改数据以后提交

5,删除:
cu.execute("delete from catalog where id = 1")  cx.commit() 以上简单的操作反应的Python SQLITE数据库操作的基本要点,这里点到为止.然后,SQLite的强大,并不仅限于此,其对SQL高级特性的支持及其小巧灵活的特点,使得SQLite在众多领域受到开发者的青睐.

举例:

#-*- encoding:gb2312 -*-
import sqlite3

conn = sqlite3.connect("D:/aaa.db")
conn.isolation_level = None #这个就是事务隔离级别,默认是需要自己commit才能修改数据库,置为None则自动每次修改都提交,否则为""
# 下面就是创建一个表
conn.execute("create table if not exists t1(id integer primary key autoincrement, name varchar(128), info varchar(128))")
# 插入数据
conn.execute("insert into t1(name,info) values ('zhaowei', 'only a test')")
# 如果隔离级别不是自动提交就需要手动执行commit
conn.commit()
# 获取到游标对象
cur = conn.cursor()
# 用游标来查询就可以获取到结果
cur.execute("select * from t1")
# 获取所有结果
res = cur.fetchall()
print 'row:', cur.rowcount
# cur.description是对这个表结构的描述
print 'desc', cur.description
# 用fetchall返回的结果是一个二维的列表
for line in res:
    for f in line:
        print f,
    print
print '-'*60

cur.execute("select * from t1")
# 这次查询后只取一个结果,就是一维列表
res = cur.fetchone()
print 'row:', cur.rowcount
for f in res:
    print f,
print
# 再取一行
res = cur.fetchone()
print 'row:', cur.rowcount
for f in res:
    print f,
print
print '-'*60

cur.close()

conn.close()


fc_lamp推荐阅读:
  评论这张
 
阅读(5416)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017