开发人员:开放源代码
为 Python Server Pages 和 Oracle 构建快速 Web 开发环境
作者:Przemyslaw Piotrowski
通过可靠的 Oracle 数据库 10g、可伸缩的 Apache Web 服务器以及直观的、面向对象的 Python 编程语言学习高级 Web 编程。
2006 年 7 月发布
各种在 Web 服务器和数据库之间充当中间层的服务器端技术使当今的开发人员获益匪浅,这些技术包括 JavaServer Pages (JSP)、Active Server Pages (ASP)、PHP 以及 PL/SQL Server Pages(如果您是一位 Oracle 开发人员)。
我在 2003 年首次接触 Python 编程语言,并从那时起开始沉迷于这种语言的独特魅力及其简便的使用。它是一种高级语言,几乎类似于以纯英文编写,就好像编程人员对于伪代码的认识。Python 的动态本质使您能够编写最简明的代码来完成甚至最复杂的任务。
在这篇文章中,我将简要介绍一种创建完整的 Python Server Pages/Oracle 数据库 10g 快速 Web 开发环境的简单方法。本文假设您没有在 Windows 或 Linux 系统上安装任何组件。(如果已安装,则可以相应地跳过某些步骤。)所有提到的组件都可免费下载,并且不需要任何许可费用。
Python 和 Python Server Pages 的背景
Python 提供了强大的自我检测功能、可动态键入、完全面向对象,并具有可扩展性以及平台独立性(Windows、Linux、Solaris、Mac OS、Nokia / S60、Pocket PC 等等)。它使您能够获得高生产率并以结果为导向,重在解决问题而非应对语言固有特性。Python 的可读性很强,非常易于维护(通过对代码样式提出特定要求)。我有许多实际上可以执行复杂任务的 Python 单行程序(有时是双行程序,如果包含导入语句),它们远比“hello-world”那样的程序功能强大。
Python 最大的优势之一是其广泛的标准库,其中提供了可用于大多数编程任务的现成模块组(Python 编程人员称其为“带电池的策略”),包括文件 I/O、系统交互、联网、数据分析和操作、线程、监测、单元测试、自我检测、XML 处理等等。
您将会着迷于利用 Python 获得的开发速度 — 最终可以让计算机理解而不是误解您的意图。此外,利用内置的文档字符串 (docstring) — 即内嵌的帮助字符串,其他编程人员可以快速理解您的类或函数的精髓。(从源代码创建文档轻而易举。)正是由于这些原因,Google 和 NASA 使用了大量的 Python,而 Microsoft 正在 .NET 平台上开发自己的 Python 版本,称为 IronPython。
Python Server Pages (PSP) 之于 Python 正如 Java Server Pages 之于 Java。较之以常规 CGI 处理的页面,利用 PSP 呈现的页面的执行效果要好 50 倍。Mod_python 包含了许多专门的模块,使得 Web 开发更简单。
解决方案组件
完整的 Web 开发环境至少必须包含三个基本组件:Web 服务器、数据库以及服务器端后端技术。此外还有一些功能要求,例如可靠性、可伸缩性以及互操作性。为了满足上述条件,我选择使用 Apache HTTP Server 2.0、Oracle 数据库 10g 快捷版 (XE) 以及 Python 2.4(带有 mod_python 和 cx_Oracle 模块)。(请阅读并找出选择这三项的原因。)
不但 Linux 用户仍然无需键入太多内容,就是 Windows 用户也必定享受所有这些组件的简单安装方式(只需单击 Next)。我已经简化了安装过程,以利用可用的二进制文件。
Oracle 数据库 10g 快捷版
2006 年 2 月,Oracle 推出了 Oracle 数据库快捷版的生产版。它是 Oracle 数据库 10g 第 2 版的小型入门级版本,其开发、部署以及分发完全免费。
Oracle 数据库快捷版适用于 Windows 和 Linux 操作系统,是 PHP、Java 或 .NET 开发人员的首选。此外,利用大量可用的第三方模块和驱动程序,可以通过各种不同的编程语言(包括 Python)访问该数据库。
Oracle 数据库快捷版具有西欧与通用两种版本。前者只支持 LATIN1 字符,而后者的默认字符集为 AL32UTF8。通用版本还包括翻译为巴西葡萄牙文、中文(简体和繁体)、英文、法文、德文、意大利文、日文、韩文以及西班牙文的管理界面。没有人愿意仅限于使用 LATIN1,因此我建议安装并使用通用版。
安装并运行 Oracle 数据库快捷版
下载适用于 Windows 的 OracleXEUniv.exe 或适用于基于 RPM 的 Linux 版本的 oracle-xe-univ-10.2.0.1-1.0.i386.rpm。(Oracle 数据库快捷版也适用于 Debian,但这超出了本文档的讨论范围。)
在 Windows 平台上:
- 使用具有管理员权限的帐户登录 Windows。
- 如果系统之前已设置了 ORACLE_HOME 变量,请将其移除。
- 双击第一步中下载的安装可执行文件。
- 在 Oracle Database 10g Express Edition - Install Wizard 中,单击 Next。
- 在 License Agreement 窗口中,选择 I accept,然后单击 Next。
- 当 Choose Installation Location 窗口弹出后,您可以接受默认目录,也可以通过单击 Browse 按钮选择所需的目标位置。完成该步骤后,单击 Next。
- 如果系统提示输入端口号,您应当指定一个。Oracle 数据库快捷版的默认端口号是
- 1521,用于 Oracle 数据库监听器
- 2030,用于 Oracle Services for Microsoft Transaction Server
- 8080,用于可通过 Web 浏览器访问的 XE 图形化管理界面
- 现在,需要为 SYS 和 SYSTEM 数据库管理员帐户设置口令。在 Specify Database Passwords 窗口中,输入所需的口令并进行确认。单击 Next。
- Summary 窗口将显示整个过程中设置的安装参数。如果您接受这些参数,则单击 Install 开始安装。
- 单击 Finish 完成安装过程。如果希望启动管理浏览器界面,请选择 Launch the Database homepage 选项。您已在 Windows 上成功安装了 Oracle 数据库快捷版。
在 Linux 平台上:
- 以 root 用户身份登录。
- 将当前的路径更改为您在第一步中下载 RPM 安装程序的目录。
- 运行以下文件启动安装过程:
# rpm -ivh oracle-xe-univ-10.2.0.1-1.0.i386.rpm
(安装过程开始。)
- 现在,当系统提示运行以下命令时,需要为已安装的数据库设置参数:
-
# /etc/init.d/oracle-xe configure
- 输入以下详细信息:
- 用于 Oracle 数据库快捷版图形用户界面的 HTTP 端口(默认为 8080)
- 用于 Oracle 数据库监听器的端口(默认为 1521)
- 用于 SYS 和 SYSTEM 管理数据库帐户的口令
- 在系统重启后是否希望自动启动该数据库
- 您可以随时运行以下命令来重新配置数据库:
# /etc/init.d/oracle-xe configure
- 要通过启动或停止数据库实例来对其进行控制,可使用随 XE 一起安装的菜单选项,或从命令行运行以下命令:
# /etc/init.d/oracle-xe start
或
# /etc/init.d/oracle-xe stop
现在,您可以通过在浏览器中打开 http://127.0.0.1:8080/apex/ 来登录 XE 的图形管理界面。(如果数据库是使用自定义参数配置的,则需相应地更改路径。)
安装 Apache HTTP Server 2.0
根据最新的统计数据,目前 Apache HTTP Server 至少部署在全球三分之二的 Web 服务器上。由于其甚至可以支持伸缩性最强的体系结构,所以它可用于各种系统平台,包括 Microsoft Windows 和 Linux。
然而,Apache 不仅仅是一个 Web 服务器。Apache Software Foundation 支持许多开放源代码的企业级产品,包括著名的 Struts 框架、Tomcat servlet container、Derby 数据库、Axis 平台、FOP 处理器以及 Xerces parser 等等,数不胜数。Apache HTTP Server 非常易于配置,并为各种服务器端配置提供了无与伦比的灵活性。此外,正如您所知,它还可充当 Oracle HTTP Server 的核心。
在 Windows 平台上:
- 以管理员身份登录并 下载 MSI Installer apache_2.0.55-win32-x86-no_ssl.msi;双击该程序开始安装过程。
- 屏幕上将显示 Apache HTTP Server 2.0 - Installation Wizard。单击 Next 继续。
- 在 License Agreement 窗口中,选择 I accept the terms in the license agreement,并单击 Next。
- 您将在 Read This First 窗口中看到一些 Apache HTTP Server 信息,单击 Next 继续。
- Server Information 对话框将出现。此时,需要输入以下信息:
- Network Domain — 服务器目前所在或即将注册到的 DNS 域,对于完整的 DNS 名 py.oracle.com,只需输入 oracle.com 即可。
- Server Name — 服务器的完整 DNS 名,不能像上面的 Network Domain 那样省略任何信息。
- Administrator's Email Address — 默认情况下,该电子邮件将与该服务器生成的错误消息一同显示给客户端。
- 选择要为其安装 Apache Server 的帐户,可以是 for All Users(所有用户),也可以是 only for the Current User(仅当前用户)。(如果您不希望 Apache 损坏 Oracle 数据库快捷版的默认 HTTP 8080 端口,我建议您选择第一个更为方便的选项。)
- 设置完这些参数后,请单击 Next。
- 在下一个 Setup Type 窗口中,您需要选择是进行 Typical 还是 Custom 安装。除非您希望更改目标位置,否则使用 Typical 安装,这将跳过用于编译模块的标题和库。(在以后的步骤中将使用预编译的模块。)此时,我将 Apache 安装目录命名为 APACHE_HOME。单击 Next 继续。
- 当 Ready to Install the Program 窗口显示后,单击 Install 启动安装过程。
- 单击 Finish 完成安装。
在 Linux 平台上(RPM 方法):
- 如果您的系统已经包含了 Apache HTTP Server,可以跳过这一部分。大多数 Linux 版本在默认情况下安装有 Apache,但您需要确保安装有 2.0.x 版。(使用 rpm -qa | grep apache 命令进行自我检测。)
- 下载 httpd-2.0.55-1.i386.rpm。
- 运行以下命令进行安装:
# rpm -ivh httpd-2.0.55-1.i386.rpm
( APACHE_HOME 的默认位置可能根据 --prefix 参数而有所不同,一般为 /usr/local/apache2。)
- 从源过程进行安装在 http://httpd.apache.org/docs/2.0/install.html 上有述;如果您的版本无法处理 RPM,那么此处提供的内容将是不错的指导信息。
要检查 Apache HTTP Server 是否运行正常,请转至 http://127.0.0.1/ 并查看是否显示了默认欢迎页面。
但是,Apache 的配置不完整,您仍需要安装 Python 和 mod_python。请按照以下步骤,在您的操作系统上完成 Python 解释器的安装。
安装 Python
在 Windows 平台上:
- 转至 http://www.python.org/,并在 Quick Links 部分中找到指向 MSI 文件(名为 Windows Installer)的直接链接。(截至本文撰写之日,Python 的当前版本为 2.4.3)。将 python-2.4.3.msi 文件保存到计算机上。
- 以拥有管理权限的用户身份登录,双击下载的安装程序可执行文件。以下屏幕将出现,您需要选择是为所有用户还是当前登录用户安装 Python。选择所需的选项后,单击 Next。
- 在 Select Destination Directory 窗口中,保留默认路径或将其更改为所需的目标位置,并单击 Next。
- 此时,您可以启用或禁用要在系统上安装的特性。建议您保留所有这些项的默认状态,但是如果您决定只包含其中的一部分,则可以随意进行更改。选定所需特性后,单击 Next 开始安装。
- 单击 Finish 完成安装。
在 Linux 平台上:
Python 的 Linux 安装完全取决于系统版本。此处有很多安装选择,如果您的系统不是太旧的话,则已经使用 Python 2.4 的几率比较大。请访问 http://www.python.org/download/linux/ 查看可用选择。
安装 mod_python
我们将使用 mod_python 将 Python 连接到 Apache HTTP Server,这是一个最初由 Gregory Trubetskoy 编写并大方赠与 Apache Software Foundation 的模块。该模块自 2000 年以来在互联网上就有提供,并在 2002 年成为 Apache 模块组的一部分。
Mod_python 使您能够访问许多低级 Apache 内部信息,并提供比其他基于 Apache 的服务器端解决方案(例如 mod_php 或 mod_perl)更为优异的灵活性。您不一定会使用这些内部信息,但由于我们关注的是快速 web 开发,因此将介绍它提供的完全针对 PSP 的高级接口。
通过 mod_python,您可以充分利用 Python 及其模块,编写能够以可重用模板形式进行缓存和包装的服务器页面。请注意,PSP 引擎是 mod_python 提供的众多解释器之一,但由于我们要将 Python 代码直接嵌入页面源代码,因此 PSP 是首选解决方案。
安装 mod_python
Windows 安装故障排除
在某些系统配置下,Apache 无法找到 Python 库和模块的路径。一个简单的变通方法是,更改运行 Apache 2 服务的帐户。
运行 services.msc 命令,并从可用服务列表中选择 Apache 2;右键单击并选择 Properties。在 Log On 选项卡上,设置 This account 选项,并为当前用户输入口令。按 OK 并重启该服务。
|
在 Windows 平台上:
- 从 http://www.apache.org/dist/httpd/modpython/win/3.2.8/ 下载 mod_python-3.2.8.win32-py2.4.exe,并双击下载的可执行文件。
- 单击 Next 继续。
- Mod_python 安装程序将试图找到默认的 Python 2.4 解释器。要接受选择,再次单击 Next。
- 要开始安装过程,按 Next 按钮。
- 安装结束后,安装程序将询问 Apache 2 的位置 ( APACHE_HOME)。使用树形浏览器导航到正确的目录,并按 OK。
- 单击 Finish 完成安装。
在 Linux 平台上:
- 该步骤需要编译模块。为此,从 http://www.apache.org/dist/httpd/modpython/ 下载 mod_python-3.2.8.tgz 文件,并将其置于 Linux 系统的 /tmp 目录中。
- 您需要将 mod_python 编译为动态共享对象 (DSO),以便在运行时由服务器进行加载。这使您无需重新编译 Apache 服务器即可对其进行编译。理想情况下,/tmp 目录下的 ./configure; make 应当足以编译该模块。根据系统配置,可能会出现需要手动指定 Apache、Python 和/或 Flex 位置的情况。如果遇到编译错误,请查阅官方 mod_python 安装指南。
- 最后,需要安装已编译的模块。您需要以 root 身份进行安装。仍然在 /tmp 目录下,运行 $ make install 并等待直至该执行操作完成。
配置 Apache HTTP Server 处理 PSP
安装完 mod_python 之后,必须要让 Apache 知晓。为此,请打开 APACHE_HOME/conf/httpd.conf 进行编辑(请查阅系统文档,以了解 httpd.conf 在 Linux 上的默认位置),并将以下代码行追加到末尾:
LoadModule python_module modules/mod_python.so
AddHandler mod_python .psp .psp_
PythonHandler mod_python.psp
PythonDebug On
第一行将 mod_python 加载到 Apache 中。mod_python.so 的实际路径可能会有所变化,但安装程序应在完成时给出正确的路径。(在 Linux 平台上,该路径很可能是 libexec/mod_python.so。)第二行将通知 Apache 应由第三行指定的 PythonHandler 处理的文件(以下部分将详细介绍 .psp_ 的用法)。最后一条指令会将 mod_python 切换到调试模式;在 PythonDebug 指令设为 On 时,它将在运行的应用程序中针对第一个未处理的异常转储跟踪。强烈建议在开发中设置该标志,但请确保在生产环境中将其关闭,以免向访问者暴露某些系统内部信息。
如果希望将 mod_python 页面用作默认索引页面,请在 httpd.conf 中找到以下行,并将其从
DirectoryIndex index.html index.html.var
更改为
DirectoryIndex index.html index.psp index.html.var
现在,重启 Apache。在 Windows 平台上,通常利用系统栏中的 Apache Monitor,或通过运行 net stop apache2 然后运行 net start apache2 来进行重启;在 Linux 平台上,重启就像 apachectl restart 一样简单。
使用 mod_python
PSP 是纯文本文件,其中包含带有 <% 和 %> 标记的 Python 代码。Python 表达式包含在 <%= 和 %> 标记中。 指令支持将其他 PSP 页面包含在内;它们由 <%@ 和 %> 标记包装。最不常用的标记是 <%-- 和 --%>,如您所猜,这两个标记只是不会出现在结果代码中的 注释。
让我们看一个简单的 Hello Python 示例。在 APACHE_HOME/htdocs 下,创建一个具有以下内容的文件 hello.psp:
<html>
<%
import sys
%>
Hello!You have <%=len(sys.modules)%> Python modules at your command.
</html>
现在,利用浏览器转至 http://127.0.0.1/hello.psp。您将会看到系统上安装的 Python 模块数量。当然,该信息对于我们而言用处不大。Mod_python 没有提供作用等同于 PHP 的 phpinfo() 的函数,该函数可以给出详细的解释器信息。在下一步中,我们将亲自为 PSP 编写一个函数。
在 APACHE_HOME/htdocs 下,创建一个具有以下内容的文件 pspinfo.psp:
<%%
req.content_type = 'text/plain'
import mod_python
import pprint
import sys
%>
PYTHON <%%=sys.version %>
MOD_PYTHON <%%=mod_python.version %>
PATH = <%%=pprint.pformat(sys.path)%>
AVAILABLE MODULES
<%%=pprint.pformat(sys.modules)%>
现在,打开 http://127.0.0.1/pspinfo.psp,您应当看到类似于下图所示的结果。
PSP 使用 Python 代码输出部分页面,这些页面使用以缩进为特征的块(类似 Python 本身)。最后一个缩进会一直存在,直至文档末尾或另一个 Python 块。请看以下示例 (blocks.psp)。
<%
for i in range(5):
j = 2**i
# Loop block begins
%>
<%="%d<sup>%d</sup>=%d"%(2, i, j)%>
<%
# This will close the loop block
%>
Outside the loop block
在上例中,我同时使用了代码块 ( <% %>) 和表达式 ( <%= %>)。编写自己的脚本时,请留意二者之间的不同:表达式只能包含一个 Python 语句。如果您认为这种说法难以理解,请重新回顾一下前一步骤中的 Apache 配置。是否还记得 AddHandler mod_python .psp .psp_ 指令?现在,我们将利用调试 .psp_ 地址来看看幕后发生的事情。转至 http://127.0.0.1/blocks.psp,您将看到 PSP 生成的 Python 代码与源代码并排而列。
这对于我们深入了解呈现引擎非常有用。它还阐释了 mod_python 引擎背后的逻辑:在执行之前,PSP 页面会呈现为纯 Python 代码。
开始开发基本的 PSP 应用程序之前,最后需要了解的是会话和表单处理。请考虑以下这个基本的登录示例 (basic_login.psp)。页面上提供的口令应是反序 UID:
<%
if 'uid' in form and 'passwd' in form and form['passwd']==''.join(reversed(form['uid'])):
session['uid'] = form['uid']
%>
user <%=session['uid']%> logged in
<%
else:
%>
<form action="basic_login.psp">
UID<br<//><input type="text" name="uid"/><br/><br/>
Password<br/><input type="password" name="passwd"/><br/><br/>
<input type="submit" value="Login"/>
</form>
<%
#
%>
PSP 的特色是具有两个重要的全局变量: form 和 session。这些是标准的 Python 字典。这将给予您最大的灵活度,但在分配变量时要小心,因为它们没有覆写保护。通过设置 session 字典变量的键值,即可设置会话变量:
session['variable'] = value
注意,Python 没有限制您使用字符串或整数作为字典键 — 任何可哈希的值都适用。例如,可在会话池中存储一个文件对象,以便在会话期间随时引用它。Mod_python 平等对待 GET 和 POST 请求,将它们存储在 form 字典中,易于查看用户是否已设置了该值。Python 字典有一些非常有用的内置方法,此时最便于使用的是:
- D.keys() — 返回字典 D 键列表
- D.has_key(k) — 如果字典 D 具有键 k,则返回 True,否则返回 False
- D.get(k[, d]) — 如果 D 具有键 k,则返回值 D[k],否则返回 d( d 默认为 None);这在表单处理中非常有用,例如 <%=form.get('is_sure', 'not sure')%>
cx_Oracle
利用 cx_Oracle Python 模块,可以轻松实现对 Oracle 数据库的访问。该模块由 Anthony Tuininga (Computronix) 根据 DB API 2.0 规范开发,这意味着,您使用同样的方法和属性组就可连接到 MySQL 或 PostgreSQL。
Cx_Oracle 具有 DB API 2.0 规范 ( PEP 249) 的所有方法和属性,除了 nextset() 游标方法和 Binary() 构造函数。然而,请注意,cx_Oracle 向标准 API 引入了许多自己的扩展,从而极大地加强了与 Oracle 数据库的合作。这些扩展在 cx_Oracle 文档中都有详细描述,但一般而言,如果您过去使用的是 DB API 2.0,那么这些扩展对您来说应该毫不陌生。
安装 cx_Oracle
在 Windows 平台上:
- 下载 cx_Oracle-4.1.2-win32-10g-py24.exe,并双击下载的安装程序。
- 单击 Next 继续。
- 该安装程序将试图找到默认的 Python 2.4 解释器。要接受该选择,单击 Next。
- 要开始安装过程,按 Next 按钮。
- 单击 Finish 完成安装。
在 Linux 平台上:
- 下载 cx_Oracle-4.1.2-10g-py24-1.i386.rpm,并将其置于系统的 /tmp 目录下。
- 在 /tmp 目录下运行:
$ rpm -ivh cx_Oracle-4.1.2-10g-py24-1.i386.rpm
使用 cx_Oracle
正如前面所述,cx_Oracle 基于 DB API 2.0 规范,因而用户使用起来非常简单。请参考以下示例,以熟悉连接至数据库并发出查询的基本步骤。在 APACHE_HOME/htdocs 下,创建文件 ora.psp 以查看 cx_Oracle 模块是否运行正常。(使用适用于配置的值替换用户名和口令。):
<%
import cx_Oracle
db = cx_Oracle.connect('username', 'password', '127.0.0.1/XE')
c = db.cursor()
c.execute('select * from dual')
req.write(c.fetchall()[0][0])
db.close()
%>
当您打开 http://127.0.0.1/ora.psp 后,应当将浏览器中的 X 字符视为系统 DUAL 表中的唯一值。
后续步骤
刚才您为 PSP 和 Oracle 数据库 10g 设置了一个完整的工作环境,还了解了 Python Web 开发的基本知识。现在,您可以按照这个思路利用 PSP 编写复杂的应用程序,或切换至 mod_python 的 Publisher Handler,以提供更好的 MVC(模型-视图-控制器)策略。
目前有数个可用于 Python 的应用程序框架。尽管我建议您可以试一试,但这些框架要在企业级环境中使用还需进一步改进。Apache 以及 mod_python 本身对于处理大多数开发任务已经足够强大了。
Przemyslaw Piotrowski 是一名信息技术专家,专门研究新兴技术和动态、灵活的开发环境。他拥有很强的 IT 专业技术背景(包括管理、开发和设计),并发现了许多软件互操作方法。他的个人网络日志是 prpi.blogspot.com。 |