结合使用 Oracle Database 11g 和 Python
本教程介绍如何结合使用 Python 和 Oracle Database 11g。
所需时间
大约 1 个小时
概述
Python 是一种流行的通用动态脚本语言。随着框架的兴起,Python 也成为 Web 应用程序开发的常用工具。如果您希望结合使用 Python 和 Oracle 数据库,本教程将通过一些示例帮助您快速入门。如果您是初次接触 Python,请参阅 附录:Python 入门,了解这种语言。
前提条件
为了学习该动手实践讲座,需要安装以下软件:
.
Oracle Database 11gR2,用户名为“pythonhol”,口令(区分大小写)为“welcome”。该模式中的示例表取自 Oracle 的 Human Resources(即“HR”)模式。
.
带有 cx_Oracle 5.0.2 扩展的 Python 2.4。
.
Django 1.1 框架。
.
本教程使用的所有文件都位于您登录的 /home/pythonhol 目录中。
连接到 Oracle
要创建到 Oracle 的连接,执行以下步骤:
.
查看 $HOME目录的 connect.py文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
print con.version
con.close()
为了提供用于访问 Oracle 数据库的 API,导入了 cx_Oracle 模块。可以用这种方法在 Python 脚本中包括多个内置的和第三方模块。
用户名“pythonhol”、口令“welcome”和连接字符串传递给 connect() 方法。在本示例中,使用了 Oracle 的简单连接 (Easy Connect) 连接字符串语法。该字符串由您计算机的 IP 和数据库服务名称“orcl”组成。
close() 方法关闭连接。脚本结束时,将自动释放所有非显式关闭的连接。
在命令行终端,运行:
python connect.py
如果连接成功,则输出版本号。如果连接失败,则引发异常。
.
在 Python 中使用缩进指明代码结构。与许多其他语言不同,没有语句终止符,也不使用 begin/end 关键字或花括号指明代码块。
在编辑器中打开 connect.py。将输出语句缩进两个空格,保存该文件:
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
print con.version
con.close()
运行该脚本:
python connect.py
用于缩进的空格或 Tab 键的数量并不重要,只要每个代码块中保持一致即可。这个示例中,Python 解释器认为 connect() 调用后面不应有新的代码块级,因此对存在的不同缩进发出警告。
在其他情况下,例如,在“if”和循环块中(稍后介绍),需要注意使每个块中的所有语句都具有相同的缩进。
如果您从本教程复制和粘贴代码,请在运行每个示例前检查粘贴的缩进是否正确。
.
Python 将一切都当作对象来处理。“con”对象有一个“version”属性,是一个字符串。
对该脚本进行更改,使其也使用“split”字符串方法:
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
ver = con.version.split(".")
print ver
con.close()
在命令行终端重新运行该脚本:
python connect.py
输出是一个“列表”,“列表”是 Python 使用的一种数组的名称。
.
可以通过索引访问 Python 列表。
将 connect.py 更改为:
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
ver = con.version.split(".")
print ver
print ver[0]
print ver[-1]
print ver[1:4]
con.close()
在命令行终端重新运行该脚本:
python connect.py
Python 列表是以零为基数的,因此 ver[0] 输出该列表的第一个元素。该列表的最后一个元素是 ver[-1]。ver[1:4] 创建了一个列表切片。这将返回从位置 1 开始到位置 4 的元素,但不包括位置 4 的元素。
.
Python 列表有一些方法,也可使用运算符来操作列表。
将 connect.py 更改为:
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
ver = con.version.split(".")
print ver
print ver.index("1")
ver.remove("2")
print ver
ver1 = ["11", "g"]
ver2 = ["R", "2"]
print ver1 + ver2
con.close()
在命令行终端重新运行该脚本:
python connect.py
index("1") 方法返回“1”元素的索引,从零开始计数。remove("2") 方法从列表中删除一个元素。“+”运算符可用于联接两个列表。
Python 的其他数据类型还包括字典(这是一些关联数组)和名为字节组的类型(类似于列表,但不能更改)。
可以使用循环来迭代列表。
将 connect.py 更改为:
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
ver = con.version.split(".")
for v in ver:
print v
if v == "11":
print "It's 11"
else:
print "Not 11"
con.close()
确保缩进正确!
使用冒号“:”表示代码块。第一个 print 和 if 位于同一个缩进级别,因为它们两个都在循环中。
在命令行终端重新运行该脚本:
python connect.py
该循环依次输出和测试该列表中的每个值。
使用数据库驻留连接池
数据库驻留连接池是 Oracle Database 11g 的一个新特性。它对 Web 应用程序常用的短期脚本非常有用。它允许随着 Web 站点吞吐量的增长对连接数量进行扩充。它还支持多台计算机上的多个 Apache 进程共享一个小规模的数据库服务器进程池。没有 DRCP,Python 连接必须启动和终止一个服务器进程。
下图的左侧是非池化的示意图。每个脚本都有自己的数据库服务器进程。不承担任何数据库工作的脚本一直保留在连接上,直到连接关闭并且服务器终止。下图的右侧是使用了 DRCP 的示意图。所有脚本都可使用来自服务器池的数据库服务器,不再需要时将退回服务器。
负责长期运行作业的批处理脚本通常使用非池化的连接。
本教程介绍新应用程序或现有应用程序如何在不编写和更改任何应用程序逻辑的情况下使用 DRCP。执行以下步骤:
.
查看 $HOME目录的 connect_drcp.py文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol', 'welcome', '127.0.0.1:/orcl:pooled',
cclass = "HOL", purity = cx_Oracle.ATTR_PURITY_SELF)
print con.version
con.close()
该脚本与 connect.py 非常类似,但连接字符串后面添加了“:pooled”。还向 connect() 方法中传递了一个连接类“HOL”,并且将该连接的“purity”定义为 ATTR_PURITY_SELF 常量。
该连接类告诉数据库服务器池这些连接是相关的。不同连接调用之间的会话信息(如默认的数据格式)可能会保留,以改善系统性能。如果之后其他应用程序通过自己的连接类名重用某个池化服务器,则会话信息将作废。
那些永不应该共享会话信息的应用程序,应使用其他连接类和/或使用 ATTR_PURITY_NEW 强制创建新会话。这虽然降低了整体可伸缩性,但避免了应用程序误用会话信息。
运行 connect_drcp.py
python connect_drcp.py
输出仍旧只是数据库版本。
无需更改脚本逻辑即可从使用 DRCP 连接池获得好处。
创建简单查询
开发 Web 应用程序时的一个常见任务是,查询一个数据库然后在 Web 浏览器中显示结果。您可以使用许多函数查询一个 Oracle 数据库,但查询的基础始终是相同的:
1. 分析要执行的语句。
2. 绑定数据值(可选)。
3. 执行语句。
4. 从数据库中获取结果。
要创建一个简单查询并显示结果,执行以下步骤。
.
查看 $HOME 目录的 query.py 文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
for result in cur:
print result
cur.close()
con.close()
cursor() 方法打开语句要使用的游标。
execute() 方法分析并执行语句。
循环从游标获取每一行并输出该行。
在终端窗口运行该脚本:
python query.py
查询结果显示为 Python“字节组”,“字节组”是一些不能更改的数组。
获取数据
从 Oracle 数据库中获取数据的方式有多种。执行以下步骤。
.
查看 $HOME 目录的 query_one.py 文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.01/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
row = cur.fetchone()
print row
row = cur.fetchone()
print row
cur.close()
con.close()
该脚本使用 fetchone() 方法只返回一行作为一个字节组。多次调用该方法后,返回连续的多行:
在终端窗口运行该脚本:
python query_one.py
两次 fetchone() 调用输出两条记录。
.
查看 $HOME 目录的 query_many.py 文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
res = cur.fetchmany(numRows=3)
print res
cur.close()
con.close()
fetchmany() 方法返回一个字节组列表。其中的 numRows 参数指定应返回三行。
在终端窗口运行该脚本:
python query_many.py
以字节组列表形式返回了表的头三行。
查看 $HOME 目录的 query_all.py 文件中包含的以下代码。
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
res = cur.fetchall()
print res
cur.close()
con.close()
在终端窗口运行该脚本:
python query_all.py
该脚本使用 fetchall() 方法返回所有行。输出仍然是一个字节组列表(Python 使用的一种数组的名称)。每个字节组包含一行的数据。
.
可以用任何 Python 方式操作该列表。编辑 query_all.py,将代码进行如下更改(黑体部分),然后再次运行该脚本。
import c