用PYTHON进行数据库编程

 
<用PYTHON进行数据库编程> 老巫 2003.09.10
19 September, 2003 
 
 
PYTHON语言进行数据库编程, 至少有六种方法可供采用. 我在实际项目中采用,不但功能强大,而且方便快捷.以下是我在工作和学习中经验总结.
 
方法一 :使用DAO ( Data Access Objects )
 
这个第一种方法可能会比较过时啦 .不过还是非常有用的. 假设你已经安装好了PYTHONWIN,现在开始跟我上路吧……
找到工具栏上 Tools à COM MakePy utilities,你会看到弹出一个Select Library的对话框, 在列表中选择 'Microsoft DAO 3. 6 Object Library' (或者是你所有的版本).
现在实现对数据的访问 :
    # 实例化数据库引擎
    import win32com.client
engine = win32com.client.Dispatch("DAO.DBEngine.35")
 
    #实例化数据库对象,建立对数据库的连接
    db = engine.OpenDatabase(r"c:/temp/mydb.mdb")
 
现在你有了数据库引擎的连接 ,也有了数据库对象的实例.现在就可以打开一个recordset了. 假设在数据库中已经有一个表叫做 'customers'. 为了打开这个表,对其中数据进行处理,我们使用下面的语法:
    rs = db.OpenRecordset("customers")
    #可以采用SQL语言对数据集进行操纵
    rs = db.OpenRecordset("select * from customers where state = 'OH'")
你也可以采用 DAO的 execute 方法 . 比如这样 :
    db.Execute("delete * from customers where balancetype = 'overdue' and name = 'bill'")
    #注意,删除的数据不能复原了 J
EOF 等属性也是可以访问的, 因此你能写这样的语句:
    while not rs.EOF:
        print rs.Fields("State").Value
        rs.MoveNext()
 
我最开始采用这个方法 ,感觉不错.
 
方法二 :使用 Python DB API,Python ODBC modules(you can use ODBC API directly, but maybe it is difficult for most beginner.)
为了在 Python里面也能有通用的数据库接口,DB-SIG为我们提供了Python数据库.(欲知详情,访问DB-SIG的网站, http://www.python.org/sigs/db-sig/). Mark
Hammond的win32扩展PythonWin里面包含了这些API的一个应用-odbc.pyd. 这个数据库API仅仅开放了一些有限的ODBC函数的功能(那不是它的目的),但是它使用起来很简单,而且在win32里面是免费的.
安装 odbc.pyd的步骤如下:
  1. 安装 python软件包 :
 2. 安装 Mark Hammond 的最新版本的 python win32 扩展 - PythonWin :
 3. 安装必要的 ODBC 驱动程序 ,用ODBC管理器为你的数据库配置数据源等参数
 
你的应用程序将需要事先导入两个模块 :
  dbi.dll - 支持各种各样的 SQL 数据类型 , 例如 :日期- dates
  odbc.pyd – 编译产生的 ODBC 接口
 
下面有一个例子 :
   import dbi, odbc     # 导入 ODBC 模块
   import time          # 标准时间模块
 
   dbc = odbc.odbc(     # 打开一个数据库连接
       'sample/monty/spam' # ' 数据源 / 用户名 / 密码 '
       )
   crsr = dbc.cursor() # 产生一个 cursor
   crsr.execute(        # 执行 SQL 语言
       """
       SELECT country_id, name, insert_change_date
       FROM country
       ORDER BY name
       """
       )
   print 'Column descriptions:' # 显示行描述
   for col in crsr.description:
       print ' ', col
   result = crsr.fetchall()      # 一次取出所有的结果
   print '/nFirst result row:/n ', result[0] # 显示结果的第一行
   print '/nDate conversions:'   # 看看 dbiDate 对象如何 ?
   date = result[0][-1]
   fmt = ' %-25s%-20s'
   print fmt % ('standard string:', str(date))
   print fmt % ('seconds since epoch:', float(date))
   timeTuple = time.localtime(date)
   print fmt % ('time tuple:', timeTuple)
   print fmt % ('user defined:', time.strftime('%d %B %Y', timeTuple))
下面是结果 :
   ------------------------------- 输出 ( output ) ----------------------------
   Column descriptions:
     ('country_id', 'NUMBER', 12, 10, 10, 0, 0)
     ('name', 'STRING', 45, 45, 0, 0, 0)
     ('insert_change_date', 'DATE', 19, 19, 0, 0, 1)
 
   First result row:
     (24L, ' ARGENTINA ', <DbiDate object at 7f1c80>)
 
   Date conversions:
     standard string:         Fri Dec 19 01:51:53 1997
     seconds since epoch:     882517913.0
     time tuple:              (1997, 12, 19, 1, 51, 53, 4, 353, 0)
     user defined:            19 December 1997
 
大家也可以去 http://www.python.org/windows/win32/odbc.html 看看 ,那儿有两个Hirendra Hindocha写的例子,还不错.
 
注意 , 这个例子中,结果值被转化为Python对象了.时间被转化为一个dbiDate对象.这里会有一点限制,因为dbiDate只能表示UNIX时间( 1 Jan 1970 00:00:00 GMT)之后的时间.如果你想获得一个更早的时间,可能会出现乱码甚至引起系统崩溃.*_*
 
方法三 : 使用 calldll 模块
(Using this module, you can use ODBC API directly. But now the python version is 2.1, and I don’t know if other version is compatible with it. 老巫:-)
 
Sam Rushing calldll模块可以让Python调用任何动态连接库里面的任何函数,厉害吧?哈.其实,你能够通过直接调用odbc32.dll里面的函数操作ODBC.Sam提供了一个包装模块odbc.py,就是来做这个事情的.也有代码来管理数据源,安装ODBC,实现和维护数据库引擎 (Microsoft Access).在那些演示和例子代码中,还有一些让人侧目的好东东,比如cbdemo.py,有一个信息循环和窗口过程的Python函数!
 
[ 你可以到 Sam's Python Software 去找到 calldll的相关连接,那儿还有其他好多有趣的东西]
 
下面是安装 CALLDLL包的步骤 :
 1. 安装 PYTHON软件包(到现在为止最多支持2.1版本)
 2. 下载 calldll-2001-05-20.zip:
     ftp://squirl.nightmare.com/pub/python/python-ext/calldll-2001-05-20.zip
  3. 在LIB路径下面创建一个新路径比如说:
     c:/Program Files/Python/lib/caldll/
 4. 在原目录下解压 calldll.zip
 5. 移动 calldll/lib/ 中所有的文件到上面一个父目录 ( calldll )里面,删除子目录(lib)
 6. CALL目录里面生成一个 file __init__.py 文件 ,象这样 :
     # File to allow this directory to be treated as a python 1.5
package.
 7. 编辑 cal ldll/odbc.py :
     "get_info_word" "get_info_long" 里面 , 改变 "calldll.membuf" "windll.membuf"
 
下面是一个怎么使用 calldll的例子 :
   from calldll import odbc
 
   dbc = odbc.environment().connection()   # create connection
   dbc.connect('sample', 'monty', 'spam') # connect to db
   # alternatively, use full connect string:
   # dbc.driver_connect('DSN=sample;UID=monty;PWD=spam')
   print 'DBMS: %s %s/n' % (    # show DB information
       dbc.get_info(odbc.SQL_DBMS_NAME),
       dbc.get_info(odbc.SQL_DBMS_VER)
       )
   result = dbc.query(          # execute query & return results
       """
       SELECT country_id, name, insert_change_date
       FROM country
       ORDER BY name
       """
       )
   print 'Column descriptions:' # show column descriptions
   for col in result[0]:
       print ' ', col
   print '/nFirst result row:/n ', result[1] # show first result row
 -------------------------------output( 输出 )--------------------------------
 
   DBMS: Oracle 07.30.0000
 
   Column descriptions:
     ('COUNTRY_ID', 3, 10, 0, 0)
    ('NAME', 12, 45, 0, 0)
     ('INSERT_CHANGE_DATE', 11, 19, 0, 1)
 
   First result row:
     ['24', ' ARGENTINA ', '1997-12-19 01:51:53 ']
 
 
方法四 : 使用 ActiveX Data Object(ADO)
现在给出一个通过 Microsoft's ActiveX Data Objects (ADO) 来连接 MS Access 2000 数据库的实例 .使用ADO有以下几个好处: 首先,与DAO相比,它能更快地连接数据库;其次,对于其他各种数据库 (SQL Server, Oracle, MySQL, etc.) 来说 ,ADO都是非常有效而方便的;再有,它能用于XML和文本文件和几乎其他所有数据,因此微软也将支持它比DAO久一些.
 
第一件事是运行 makepy.尽管这不是必须的,但是它对于提高速度有帮助的.而且在PYTHONWIN里面运行它非常简单: 找到工具栏上 Tools à COM MakePy utilities,你会看到弹出一个Select Library的对话框, 在列表中选择’ Microsoft ActiveX Data Objects 2.5 Library ‘(或者是你所有的版本).
然后你需要一个数据源名 Data Source Name [DSN] 和一个连接对象 . [ 我比较喜欢使用 DSN-Less 连接字符串 ( 与系统数据源名相比 ,它更能提高性能且优化代码 )]
MS Access 来说 ,你只需要复制下面的DSN即可 . 对于其他数据库 ,或者象密码设置这些高级的功能来说,你需要去 [ Control Panel 控制面板 | 管理工具 Administrative Tools | 数据源 Data Sources (ODBC) ]. 在那里 ,你可以设置一个系统数据源DSN . 你能够用它作为一个系统数据源名 ,或者复制它到一个字符串里面,来产生一个 DSN-Less 的连接字符串 . 你可以在网上搜索 DSN-Less 连接字符串 的相关资料 . 好了 ,这里有一些不同数据库的DSN-Less连接字符串的例子: SQL Server, Access, FoxPro, Oracle , Oracle, Access, SQL Server, 最后是 MySQL.
>>> import win32com.client
>>> conn = win32com.client.Dispatch(r'ADODB.Connection')
>>> DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
>>> conn.Open(DSN)
经过上面的设置之后 ,就可以直接连接数据库了:
首要的任务是打开一个数据集 /数据表
>>> rs = win32com.client.Dispatch(r'ADODB.Recordset')
>>> rs_name = 'MyRecordset'
>>> rs.Open('[' + rs_name + ']', conn, 1, 3)
       
[ 1和3是常数.代表 adOpenKeyset adLockOptimistic .我用它作为默认值,如果你的情况不同的话,或许你应该改变一下.进一步的话题请参考ADO相关材料 .]
打开数据表后 ,你可以检查域名和字段名等等
>>> flds_dict = {}
>>> for x in range(rs.Fields.Count):
 ...     flds_dict[x] = rs.Fields.Item(x).Name
       
字段类型和长度被这样返回 A :
>>> print rs.Fields.Item(1).Type
202 # 202 is a text field
>>> print rs.Fields.Item(1).DefinedSize
50 # 50 Characters
       
现在开始对数据集进行操作 .可以使用SQL语句 INSERT INTO 或者 AddNew() Update ()
>>> rs.AddNew()
>>> rs.Fields.Item(1).Value = 'data'
>>> rs.Update()
这些值也能够被返回 :
>>> x = rs.Fields.Item(1).Value
>>> print x
'data'
       
因此如果你想增加一条新的记录 ,不必查看数据库就知道什么 number AutoNumber 字段已经产生了
>>> rs.AddNew()
>>> x = rs.Fields.Item('Auto_Number_Field_Name').Value 
# x contains the AutoNumber
>>> rs.Fields.Item('Field_Name').Value = 'data'
>>> rs.Update()
使用 ADO,你也能得到数据库里面所有表名的列表:
        >>> oCat = win32com.client.Dispatch(r'ADOX.Catalog')
        >>> oCat.ActiveConnection = conn
        >>> oTab = oCat.Tables
        >>> for x in oTab:
        ...     if x.Type == 'TABLE':
        ...         print x.Name
       
关闭连接 . 注意这里C是大写,然而关闭文件连接是小写的c.
    >>> conn.Close()
       
前面提到 ,可以使用SQL语句来插入或者更新数据,这时我们直接使用一个连接对象.
  >>> conn = win32com.client.Dispatch(r'ADODB.Connection')
>>> DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
>>> sql_statement = "INSERT INTO [Table_Name]
 ([Field_1], [Field_2]) VALUES ('data1', 'data2')"
>>> conn.Open(DSN)
>>> conn.Execute(sql_statement)
>>> conn.Close()
       
最后一个例子经常被看作是 ADO的难点.一般说来,想要知道一个表的RecordCount 的话,必须象这样一个一个地计算他们 :
>>> # See example 3 above for the set-up to this
>>> rs.MoveFirst()
>>> count = 0
>>> while 1:
...     if rs.EOF:
...         break
...     else:
...         count = count + 1
...         rs.MoveNext()
       
如果你也象上面那样些程序的话 ,非常底效不说,如果数据集是空的话,移动第一个记录的操作会产生一个错误.ADO提供了一个方法来纠正它.在打开数据集之前,设置CursorLocation 为3. 打开数据集之后,就可以知道recordcount了.
        >>> rs.Cursorlocation = 3 # don't use parenthesis here
        >>> rs.Open('SELECT * FROM [Table_Name]', conn) # be sure conn is open
        >>> rs.RecordCount # no parenthesis here either
        186
       
[再:3是常数]
这些只用到 ADO的皮毛功夫,但对于从PYTHON来连接数据库,它还是应该有帮助的.
(单步执行还可以,为何写为script就不行?老巫疑惑)
 
 
方法五 :使用 mxODBC模块(在Windows和Unix下面都可以用,但是是商业化软件,要掏钱的.)下面是相关连接:
 
 
方法六 : 对具体的数据库使用特定的PYTHON模块
MySQL数据库 à MySQLdb模块,下载地址为:
PostgresSQL数据库 à psycopg模块
PostgresSQL的主页为: http://www.postgresql.org
Python/PostgresSQL模块下载地址: http://initd.org/software/psycopg
Oracle数据库 à DCOracle模块下载地址: http://www.zope.org/Products/DCOracle
 
=======================================
版权所有 @ Copyright 老巫 2003
本文可原封不动的拷贝和自由地再发行,但在拷贝和再发行的拷贝中必须
原封不动地含有这段版权声明。
http://www.wufuheng.com
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值