在你开始前
本教程适用于想要学习如何将XML格式的数据存储在数据库中,如何从Python应用程序连接到DB2以及如何将数据从CSV文件转换为XML文档的开发人员。 假定没有Python的先验知识(您将在本教程中学习如何安装Python),但这将是有利的。 本教程假定您使用Microsoft®Windows®操作系统,但是代码无需修改即可在其他平台上运行。 完成本教程后,您将具备创建强大的Python应用程序的技能,这些应用程序可以与IBM DB2数据库进行通信和交互,并利用pureXML提供的功能。
关于本教程
长期以来,IBM DB2数据库管理系统一直是关系数据管理领域的领导者。 然而,近年来,对本质上更加灵活和面向文档的数据结构的需求已大大增加。 这种数据结构最突出的例子之一就是XML。
尽管许多关系数据库系统都急于在其数据库中加入某种形式的XML支持,但IBM DB2是唯一允许XML本机存储在数据库中的应用程序,它保持原始格式不变。 这被称为pureXML-一种技术,它允许DB2开发人员和DBA与关系数据一起对XML数据进行操作和报告,而不会负面影响XML本身的纯度。
在本教程中,您将开发一个Python脚本,该脚本将连接到美国人口普查局网站,并下载CSV文件,其中包含有关国家,区域和州范围内的人口数据,包括2000年人口普查结果和从那时起,每年的波动都基于估算值。 然后,您将学习如何处理该数据,将其转换为XML文档。 然后,您将使用Python将数据插入到DB2中,而不是导入这个大文档并依靠DB2函数将其切成小块并切成单独的行,并且将XML文档存储在CSV文件中的每个相关行中。 最后,您将创建一个命令行应用程序,该应用程序将针对此数据生成一些有用的报告,并按照人口从高到低的顺序显示州,地区或国家/地区的列表。
先决条件
要遵循本教程中的步骤,您将需要安装以下软件:
- IBM DB2 Express-C 9.5或更高版本
- Python版本2.6或任何3.0之前的版本
请参阅相关主题的链接来下载这些先决条件。 本教程假定您使用的是Microsoft Windows操作系统,最好是XP或更高版本。 为了安装Python和用于Python的IBM DB2扩展,您将需要计算机上的管理特权。
设置数据库
在本部分中,您将使用DB2 Command Editor实用程序创建一个新的IBM DB2数据库,然后创建一系列将以XML格式存储人口普查数据的表。 您将创建三个表:国家,地区和州。 这些表中的每一个表都将为表中的每一行存储一个唯一的ID,以及一个XML文档,该文档将存储您将从本教程后面的美国人口普查局CSV文件中导入的人口普查数据。
创建数据库
让我们开始吧。 打开DB2命令编辑器(“ 开始”>“程序”> IBM DB2> [DB2实例名称]>“命令行工具” ),然后输入以下命令: create database census using codeset UTF-8 territory US
。
此过程可能需要一两分钟才能完成,因此请耐心等待。 完成后,您将收到类似以下的响应消息: DB20000I The CREATE DATABASE command completed successfully
。
提示:您可以通过按Ctrl + Enter快速在命令编辑器中执行命令。
现在,使用以下命令connect to census
新创建的人口普查数据库: connect to census
。
再次,您应该收到来自DB2服务器的响应,这一次是这样的: A JDBC connection to the target has succeeded
。
现在已创建数据库,您准备创建将存储应用程序数据的表。
创建数据库表
您将人口数据加载到数据库中,并将其存储在三个单独的表中:国家,地区和州。 现在在清单1中创建这些表。
清单1.用于创建表的DDL SQL语句
create table country (
id int not null generated by default as identity,
data xml not null,
primary key(id)
);
create table region (
id int not null generated by default as identity,
data xml not null,
primary key(id)
);
create table state (
id int not null generated by default as identity,
data xml not null,
primary key(id)
);
这些表中的每个表都存储相同类型的数据-每次插入行时DB2都会自动生成的唯一标识符,以及将为每行存储XML文档的XML数据列。 严格来说,您可以在此处使用单个表并在其上创建类型列,以确定行是国家,地区还是州,但是如果将它们分成表,则可以为将来的操作提供更大的灵活性。
当执行上述SQL语句时,DB2应该为每个表返回以下响应: DB20000I
。 SQL命令成功完成。
配置数据库后,您现在就可以安装和配置Python以及适用于Python的ibm_db扩展。
安装和配置Python
Python是一种高级编程语言,非常注重代码的可读性。 与许多其他编程语言不同,代码缩进和样式由开发人员决定,在Python中,您必须使用缩进来表示代码块(例如类,if语句和循环)。 Python易于学习,可生成简洁明了的代码,并且在许多不同的平台上得到广泛支持,这使其成为许多不同应用程序开发项目的绝佳选择。
关于Python
尽管通常在Mac OS X和Linux®操作系统上预先安装了Python,但对于Microsoft Windows却不能这样说。 幸运的是,您可以从Web下载Python并将其安装在Windows上,您将在本节中学习如何做。 但是,在开始之前,值得一提的是,在下载适用于Windows的Python时,您有很多选择。
第一种选择是使用开放源代码的官方二进制安装程序,该程序可从官方Python网站下载。 此选项提供Python的最新版本,并在开放源代码许可中提供。 在本教程中,您将使用此Python发行版。
另外,商业化的ActiveState Python提供了一些其他资源,例如完整的文档以及其他Python扩展,包括Windows特定的扩展,这些扩展有助于使用Python开发基于Win32 API的应用程序。
安装Python
安装Python的第一步是从Python官方网站下载它(请参阅参考资料中的链接)。 在撰写本文时,Python的当前生产版本为2.6.4和3.1.1。 本教程假定您正在使用2.6。*版本的Python。 由于3.0及更高版本不向后兼容,我强烈建议您下载提供的最新3.0之前的版本(版本2.xx)。 将此文件保存到硬盘驱动器,下载完成后,打开.msi文件以启动安装程序。
启动安装程序时,它将询问您是要为所有用户还是仅为您安装(此选项在WindowsVista®中不可用)。 保留默认选择“ 为所有用户安装” ,然后按“ 下一步”继续。 现在将要求您选择目标目录。 默认值应该是C:\ Python26 \或类似的值; 再次,接受此默认设置,然后按下一步前进。 现在,您将有机会通过选择要安装的功能来自定义Python安装。 默认情况下,所有内容均处于选中状态,因此保持原样,然后按下一步开始安装。 该过程将花费几分钟,完成后,您将看到一个类似于图1中的窗口。
图1.完成Python 2.6.4安装程序窗口
按完成退出安装程序。 在继续之前,值得验证Python是否已安装并且可以正常工作。 您可以根据需要使用添加到Windows“开始”菜单中的快捷方式,但是我建议您从命令提示符处启动Python,因为这是运行本教程后面创建的脚本的方式。
首先,通过“运行”对话框打开Windows命令提示符窗口(“ 开始”>“运行” ,然后输入cmd
),或导航到“ 开始”>“程序”>“附件”>“命令提示符” )。 在提示符下,输入命令: python
。
现在,您应该在Python提示符下,由>>>表示, 如图2所示 。 (请参阅图2的纯文本视图 。)
图2. Python提示
注意:如果看到诸如python is not recognized as an internal or external command, operable program or batch file
的消息python is not recognized as an internal or external command, operable program or batch file
,则Python目录未放置在Windows路径上。 请参阅相关主题如何设置此信息。 要退出Python提示符,请输入以下命令: quit()
。
在Python提示符下输入此命令后,应返回Windows命令提示符。 在下一部分中,您将学习如何安装ibm_db Python扩展,它将允许您从Python连接到DB2数据库。
安装ibm_db Python扩展
用于Python的ibm_db扩展允许您使用Python代码连接到IBM DB2数据库并与之交互。 要安装此扩展,首先需要安装easy_install实用程序(setuptools)。 导航到setuptools的包页面(请参阅相关信息 ,并找到你的Python,这是2.6在我的情况版本的文件)。 将此文件下载到您的硬盘驱动器,完成后,将其打开以将easy_install.exe应用程序安装到您的Python Scripts目录(通常为C:\ Python26 \ Scripts)中。
安装ibm_db扩展本身非常简单。 打开Windows命令提示符窗口( 开始>运行> cmd )并输入以下命令,如果将Python安装到其他目录,请相应地更改引用: C:\Python26\Scripts\easy_install ibm_db
。
这将自动搜索,下载,解压缩和安装ibm_db扩展。 完成后,您将返回Windows命令提示符, 如图3所示 。 (请参阅图3的纯文本视图 。)
图3.成功安装的ibm_db扩展
接下来,您将通过测试与您在本教程前面创建的DB2数据库的连接来验证ibm_db扩展是否正常工作。
从Python连接到DB2
创建了DB2数据库并安装并配置了Python和ibm_db扩展之后,您现在可以检查是否可以从Python连接到DB2。 打开Windows命令提示符窗口,然后发出python命令以启动Python解释器。
在提示符下,输入以下命令以连接到DB2并计算国家表中的行数。 请注意,此处仅包含Python提示符(>>>和...),仅出于说明目的,您不应在解释器中键入这些提示符。 另外,确保用实际的DB2凭证替换清单2中代码中的凭证。
清单2.连接到DB2的Python代码
>>> import ibm_db
>>> conn =
ibm_db.connect("DATABASE=census;HOSTNAME=localhost;PORT=50000;
PROTOCOL=TCPIP;UID=username;PWD=password;", "", "")
>>> sql = "SELECT COUNT(*) FROM country"
>>> stmt = ibm_db.exec_immediate(conn, sql)
>>> result = ibm_db.fetch_both(stmt)
>>> while result != False:
... print "Count: ", result[0]
... result = ibm_db.fetch_both(stmt)
...
输入上面的最后一行后,按Enter键,代码将执行。 您应该看到一个结果( Count: 0
), 如图4所示 。
图4. DB2连接测试的结果
如果从Python连接到DB2时遇到问题,请检查ibm_db扩展名是否已正确安装,并且已经按照本教程前面所述创建了数据库。 还请验证用于连接到DB2的凭据是否正确。
建立数据库并准备好使用Python之后,您就可以开始开发本教程的主要主题了。 在下一部分中,您将从美国人口普查局下载,解析和转换CSV数据,并将其另存为XML数据到DB2数据库中。 然后,您将学习如何从数据库读取此数据并将其显示给用户。
下载和转换CSV数据
在本教程的这一部分中,您将学习如何从美国人口普查局网站上创建一个Python脚本来下拉CSV文件。 接下来,您将处理此CSV数据,并将其转换为XML,可以将其存储在本教程前面创建的DB2 pureXML数据库中。
在开始之前,您应该在硬盘上的某个位置创建一个文件夹,用于存储项目文件。 我将数据存储在文件夹C:\ pycensus中,建议您也这样做。
从美国人口普查局网站下载CSV文件
美国人口普查局可以多种不同格式下载大量数据。 不幸的是,人口普查2000年的人口数据和此后每年的估计数据仅以CSV格式提供,而没有XML。 但是,这不是问题,因为您可以使用Python从人口普查局网站上提取此CSV文件并将其转换为XML,然后将其存储在DB2 pureXML数据库中。
如果需要,可以将Web浏览器指向CSV文件项目文件夹的URL。 但是,您将创建一个Python脚本来执行此任务。 在您喜欢的文本编辑器中,创建一个新文件,并将其另存为download.py在您的项目文件夹中(例如C:\ pycensus)。 将清单3中的代码添加到此文件中。
清单3. download.py
import httplib
conn = httplib.HTTPConnection("www.census.gov")
conn.request("GET", "/popest/national/files/NST-EST2008-alldata.csv")
response = conn.getresponse()
f = open('data.csv', 'w')
f.write(response.read())
f.close()
conn.close()
在此脚本中,您使用httplib
模块连接到census.gov网站,并为所需的CSV文件发出GET
请求。 然后,您获取响应并将其写入名为data.csv的文件。 要运行此脚本,请打开Windows命令提示符,并按如下所示更改到项目目录: cd \pycensus
。
接下来,运行以下命令以运行Python脚本: python download.py
。
脚本完成后,您将返回提示。 您可能想知道为什么没有消息生成—不用担心,这是一件好事,因为这意味着没有发生错误。 在Windows资源管理器中打开您的项目文件夹,您现在会注意到文件夹data.csv中有一个额外的文件。 如果您具有MicrosoftExcel®,它将是此类文件的默认处理程序,打开该文件将产生如图5所示的结果。
图5. Microsoft Excel中的data.csv
警告:请勿将此文件保存在Excel中,因为它可能会更改CSV文件格式以适合其自身的解释,并且Python可能无法读取。 如果Excel要求您保存文件,请选择“ 否” 。 如果您不小心保存了文件,只需删除它,然后重新运行download.py Python脚本。 在下一部分中,您将学习如何获取此CSV文件并将其转换为XML。
将CSV数据转换为XML文档
要将CSV数据转换为XML,必须首先明确要存储数据的精确度,是否应以不同的方式存储不同的记录,并检查是否应丢弃某些记录。 在您刚刚下载的CSV文件的示例中,您会注意到其中包含三种类型的数据:整个国家/地区的单行信息; 东北,中西部,南部和西部区域的四行数据; 美国五十个州和哥伦比亚特区的五十一个数据行; 并排在波多黎各联邦。 文件的第一行是标题行,将用于列名。
您在本节中创建的脚本将采用标题行,并使用此数据形成XML文档中记录应具有的每个元素的标记名。 该脚本将基于前四列确定特定行是指国家,地区还是州,并将相应地设置标签名称以指示XML文档所引用的内容。 最后,该脚本将选择排除波多黎各联邦记录,因为它具有一些不完整的数据。
在文本编辑器中,创建一个新文件并将其另存为convert.py。 将清单4中的代码添加到此文件。
清单4. convert.py
import csv
reader = csv.reader(open('data.csv'), delimiter=',', quoting=csv.QUOTE_NONE)
print "<data>"
for record in reader:
if reader.line_num == 1:
header = record
else:
innerXml = ""
dontShow = False
type = ""
for i, field in enumerate(record):
innerXml += "<%s>" % header[i].lower() + field + "</%s>"
% header[i].lower()
if i == 1 and field == "0":
type = "country"
elif type == "" and i == 3 and field == "0":
type = "region"
elif type == "" and i == 3 and field != "0":
type = "state"
if i == 1 and field == "X":
dontShow = True
if dontShow == False:
xml = "<%s>" % type
xml += innerXml
xml += "</%s>" % type
print xml
print "</data>"
在此文件中,您使用csv库读取data.csv文件。 您将输出包装在开始的<data>
和结束</data>
XML标记中,因为它会生成单个文档输出。 然后,您遍历CSV文件的每一行。 如果当前行是文件的第一行,则将该记录设置为标题。 稍后将在脚本中将其用作国家,地区或州记录中每个字段的元素名称。 如果当前行不是标题记录,则遍历记录中的每一列,并创建一个内部XML元素字符串,其名称由标题记录驱动。 然后,您检查相关行是否指向国家,地区或州,并将内部XML元素包装在外部标签<country>
, <region>
或<state>
。 最后,检查记录是否在特定字段中包含X
,如果是,则将布尔指示符设置为True
,这将阻止将该特定行添加到XML文档中。 您可以通过发出以下命令来运行此脚本的第一种方式与以前相同: python convert.py
。
以这种方式运行脚本将产生如图6所示的结果。
图6. convert.py输出
如您所见,脚本已将数据直接放入屏幕。 如果将这些数据保存到文件中,它将更加有用。 无需创建更多的Python代码来执行此操作,您只需按如下所示更改发出的命令,以告诉命令提示符将输出保存到名为data.xml的文件中: python convert.py > data.xml
。
这将在项目目录中创建一个名为data.xml的新文件。 如果在读取并格式化XML的应用程序(例如Firefox)中打开此文件,则可能会看到如图7所示的结果。
图7. Mozilla Firefox中的XML输出
将数据存储在这样的文件中后,您可以使用.del文件和IMPORT
命令将XML导入DB2数据库。 但是,这导致整个XML数据存储在DB2表的一行中。 现在,可以使用XQuery拆分此数据并将其存储在单独的行中。 但是,由于您已经在使用Python创建XML文档,因此直接在convert.py脚本本身中直接执行一系列INSERT
语句要容易得多。 在下一部分中,您将修改convert.py脚本以实现此目的。
使用Python将XML保存到DB2中
以前,您学习了如何将从美国人口普查局下载的CSV数据格式化为大型XML文档。 现在,您将学习如何获取国家,地区和州的行,并将其插入到DB2数据库中。 对您在上一节中创建的convert.py文件进行本节中列出的更改。
包括ibm_db库
您需要做的第一件事是在代码中包含ibm_db库。 为此,请更改covert.py文件的第一行,使其现在显示为: import csv, ibm_db
。
使用这样的脚本,多次运行它将导致重复插入每一行,从而导致大量重复数据。 为避免这种情况,请在脚本开始时清除数据库表,以便每次运行时都从新开始。 在刚刚修改的清单4的import语句下面添加清单5 (换句话说,将其添加到清单4中的reader = csv.reader...
行之前)。
清单5. convert.py的节选—清除表
connString = "DATABASE=census;HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;
UID=username;PWD=password;"
try:
conn = ibm_db.connect(connString, "", "")
except:
print "Could not connect to DB2: ", ibm_db.conn_errormsg()
else:
print "Connected to DB2."
sql = "DELETE FROM country"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from country table: ", ibm_db.stmt_errormsg()
else:
print "Country table emptied."
sql = "DELETE FROM region"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from region table: ", ibm_db.stmt_errormsg()
else:
print "Region table emptied."
sql = "DELETE FROM state"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from state table: ", ibm_db.stmt_errormsg()
else:
print "State table emptied."
您可能还记得本教程前面部分中测试到DB2的Python连接正在工作的代码,该代码用于连接到DB2数据库。 这次,您将执行三个SQL语句-分别删除国家,地区和状态表中的所有数据。 在每种情况下,Python都会输出一条消息,要么确认语句已成功执行,要么发生错误。 如果确实发生错误,则会将DB2错误消息转发给用户,从而更容易调试出了问题。
接下来,您需要删除几个打印语句,这些语句输出在上一节中创建的单个大型文档的外部XML声明。 这些行是: print "<data>"
和print "</data>"
。
前者应位于reader = csv.reader...
行下方,而后者应为文件的最后一行。
最后,您需要更改convert.py文件,以便它不会为每一行打印XML代码,而是将其另存为XML文档在适当的DB2表中。 您已经创建了代码来确定特定行是国家,地区还是州,并为该行生成XML。 因此,您现在要做的就是创建相关的INSERT
语句并执行它。
找到当前读取print xml
。 您需要用清单6中的代码替换此行。 请记住,Python对代码缩进非常敏感,因此请确保在文本编辑器中正确排列代码。
清单6. convert.py的节选—将行保存到DB2数据库
if type == "country":
sql = "INSERT INTO country(data) VALUES('%s')" % xml
elif type == "region":
sql = "INSERT INTO region(data) VALUES('%s')" % xml
elif type == "state":
sql = "INSERT INTO state(data) VALUES('%s')" % xml
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error adding row: ", ibm_db.stmt_errormsg()
else:
print "Row added to %s table" % type
convert.py的最终代码类似于清单7 。 同样,缩进在Python中非常重要,因此请确保缩进正确,否则您可能会遇到意想不到的结果。
清单7. convert.py
import csv, ibm_db
connString = "DATABASE=census;HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;UID=jjlennon;
PWD=DopGX240;"
try:
conn = ibm_db.connect(connString, "", "")
except:
print "Could not connect to DB2: ", ibm_db.conn_errormsg()
else:
print "Connected to DB2."
sql = "DELETE FROM country"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from country table: ", ibm_db.stmt_errormsg()
else:
print "Country table emptied."
sql = "DELETE FROM region"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from region table: ", ibm_db.stmt_errormsg()
else:
print "Region table emptied."
sql = "DELETE FROM state"
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error deleting from state table: ", ibm_db.stmt_errormsg()
else:
print "State table emptied."
reader = csv.reader(open('data.csv'), delimiter=',', quoting=csv.QUOTE_NONE)
for record in reader:
if reader.line_num == 1:
header = record
else:
innerXml = ""
dontShow = False
type = ""
for i, field in enumerate(record):
innerXml += "<%s>" % header[i].lower() + field + "</%s>"
% header[i].lower()
if i == 1 and field == "0":
type = "country"
elif type == "" and i == 3 and field == "0":
type = "region"
elif type == "" and i == 3 and field != "0":
type = "state"
if i == 1 and field == "X":
dontShow = True
if dontShow == False:
xml = "<%s>" % type
xml += innerXml
xml += "</%s>" % type
if type == "country":
sql = "INSERT INTO country(data) VALUES('%s')" % xml
elif type == "region":
sql = "INSERT INTO region(data) VALUES('%s')" % xml
elif type == "state":
sql = "INSERT INTO state(data) VALUES('%s')" % xml
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error adding row: ", ibm_db.stmt_errormsg()
else:
print "Row added to %s table" % type
确保已保存此文件并打开Windows命令提示符。 转到项目目录并再次运行convert.py脚本,这一次使用以下命令(不要将输出通过管道传输到文件): python convert.py
。
您应该看到一系列“行添加到状态表”消息,一个接一个出现, 如图8所示 。
图8.修改后的convert.py的输出
在使用Python从DB2读取此数据之前,请打开DB2命令编辑器并检查该数据在数据库中的外观。 确保您已连接到普查数据库(如果需要,发出命令connect to census
)并输入以下SQL语句: select * from state
。 该查询应产生51个结果, 如图9所示 。
图9.查询结果视图
单击“查询结果”选项卡中任一行旁边的更多(...)按钮。 这将打开XML Document Viewer,显示该特定行的关联XML文档。 这看起来应该类似于图10中的屏幕截图。
图10. XML文档查看器
随意执行类似SQL语句以从国家和地区表中检索记录; 您应该为国家/地区表获得单行结果,为区域表获得四行结果。
接下来,您将学习如何将这些数据从DB2读入Python并将其呈现给用户。
使用Python从数据库读取XML
在本部分中,您将学习如何构建命令行Python应用程序,该应用程序将请求用户输入以选择三个菜单选项之一。 这些选项将允许用户查看由2000年人口普查驱动的人口排序的州,地区或国家/地区列表。
首先,您将连接到DB2数据库,打印菜单选项列表,并请求用户输入。 创建一个名为read.py的新文件,并将清单8中的代码添加到其中。
清单8. read.py的节选—入门
import ibm_db, locale, sys
locale.setlocale(locale.LC_ALL, '')
connString = "DATABASE=census;HOSTNAME=localhost;PORT=50000;
PROTOCOL=TCPIP;UID=username;PWD=password;"
try:
conn = ibm_db.connect(connString, "", "")
except:
print "Could not connect to DB2: ", ibm_db.conn_errormsg()
else:
print "Connected to DB2."
print "To view population information, please select one of the following options:"
print "1.) List of states by population"
print "2.) List of regions by population"
print "3.) List of countries by population"
print "4.) Exit the application"
input = False
while input == False:
try:
option = int(raw_input("Please enter a number from the options above to
view that information: "))
if option not in [1,2,3,4]:
raise IOError('That is not a valid option!')
except:
print "That is an invalid option."
else:
input = True
在清单8中 ,您首先要导入ibm_db和语言环境库。 需要使用语言环境库来格式化总体编号,以使其更具可读性(使用千位分隔符)。 通过将语言环境设置为计算机上的默认设置来启动应用程序。 接下来,在打印有关将对用户可用的不同菜单选项的信息之前,连接到DB2数据库。
清单8中的代码的最后一部分要求用户输入一个值,并验证它是一个整数,并且是四个可用选项之一(1、2、3或4)。如果提供的值不是这些值之一值,它将一直要求输入一个值,直到输入有效的值为止。 用户可以通过选择选项4随时退出程序。
既然应用程序确定了用户想要查看的数据,它就必须构建一个适当SQL语句来检索该数据。 清单9中的代码就是这样做的。
清单9. read.py的节选—构建SQL
selected = ""
if option == 1:
sql = "select x.* from state s, xmltable('$d/state' passing s.data as \"d\"\
columns \
name varchar(50) path 'name', \
pop int path 'census2000pop') as x \
order by x.pop desc"
selected = "state"
elif option == 2:
sql = "select x.* from region r, xmltable('$d/region' passing r.data as \"d\"\
columns \
name varchar(50) path 'name', \
pop int path 'census2000pop') as x \
order by x.pop desc"
selected = "region"
elif option == 3:
sql = "select x.* from country c, xmltable('$d/country' passing c.data as \"d\"\
columns \
name varchar(50) path 'name', \
pop int path 'census2000pop') as x \
order by x.pop desc"
selected = "country"
elif option == 4:
sys.exit()
在清单9中 ,if块检查用户的输入选择值是1、2、3还是4。如果检测到1到3之间的值,它将创建一个SQL语句来查看状态,区域或区域的填充数据。国家。 如果它检测到输入了4,它将退出程序。
每个选项SQL语句几乎相同,只是它在每个实例中查看不同的表。 它基本上使用XMLTABLE
函数将表的数据列中的XML元素映射到不同的关系样式列。 然后按填充值从最高编号到最低编号对数据进行排序。
应用程序的最后一部分是执行SQL语句并遍历结果集以生成结果表。 清单10显示了此代码。
清单10. read.py的节选—格式化结果
try:
stmt = ibm_db.exec_immediate(conn, sql)
except:
print "Error retrieving data: ", ibm_db.stmt_errormsg()
else:
res = ibm_db.fetch_both(stmt)
print ".----------------------------------------------,"
print "| |"
print "|", ("%s LIST BY POPULATION" % selected.upper()).center(44), "|"
print "| |"
print "|----------------------------------------------|"
print "|", ("%s" % selected.upper()).center(21), " | ", "POPULATION".center(18), "|"
print "|----------------------------------------------|"
while res != False:
print "|", res[0].ljust(21), " | ", locale.format("%d", res[1], grouping=True)
.rjust(18), "|"
res = ibm_db.fetch_both(stmt)
print "'----------------------------------------------'"
在此代码中,您将执行由清单9中的代码生成SQL语句,并打印出一个很好地格式化结果的表。 您将在本节中使用一系列Python函数来执行字符串操作,例如左对齐,居中和右对齐文本,并使用千位分隔符设置填充值的格式,以使其易于阅读。
完成了从数据库读取的代码后,现在可以执行脚本了。 在Windows命令提示符下,确保您位于项目目录中,并使用以下命令启动该程序: python read.py
。
程序执行时,它将连接到DB2,并为您提供以下菜单选项列表,您可以在应用程序中输入这些菜单选项:
- 各州的州列表
- 按人口划分的地区清单
- 国家人口一览表
- 退出申请
图11.应用程序菜单
尝试输入无效的菜单选项,例如字符串hello
。 在要求您再次输入选项之前,您将收到如图12所示的错误。 (请参阅图12的纯文本视图 。)
图12.无效的菜单选项错误
这次,输入一个有效的选项。 我选择了选项2(按人口列出的区域)。 这将产生如图13所示的结果。 (请参阅图13的纯文本视图 。)
图13.区域人口数据
如您所见,该应用程序将显示一个包含区域列表的表,其中显示人口最多的区域。 对于其他两个菜单选项,您应该会看到类似的结果,只是选项1将显示51个州,而选项3仅显示一个国家。
确保自己尝试不同的菜单选项,并尝试通过添加更多选项和数据的不同视图来增强应用程序。
摘要
在本教程中,您学习了如何创建具有带有本机XML数据列的表的DB2数据库。 然后,您学习了如何通过easy_install实用程序安装Python和Python的ibm_db扩展。 接下来,您确认可以通过Python解释器与DB2数据库进行通信。 然后,您开发了一个Python脚本,该脚本从美国人口普查局网站上提取了人口数据,然后再将此CSV数据转换为XML格式并将其保存在DB2表中。 最后,您创建了一个基本的命令行应用程序,该应用程序提供有关国家,区域和州范围内的人口数据的表格报告。
有了本教程中提供的信息,您应该具备进一步学习Python和DB2开发技能所需的知识。
翻译自: https://www.ibm.com/developerworks/xml/tutorials/x-csvdb2pytut/index.html