Manipule dados CSV com o Python e o pureXML

Importe e converta dados de censo dos EUA para XML usando o Python no IBM DB2 Express-C

O IBM® DB2® pureXML® lhe possibilita armazenar dados XML de forma nativa em um sistema de gerenciamento de banco de dados relacional, dando-lhe o poder e a flexibilidade de relatar estes dados sem perder as vantagens que o formato XML oferece. Neste tutorial, você aprenderá como se conectar a um banco de dados DB2 a partir da linguagem de programação Python, importando dados populacionais do United States Census Bureau. O Python será utilizado para converter este arquivo CSV para um arquivo XML, antes de inserir os dados XML de forma nativa no DB2. Finalmente, mostraremos como utilizar o Python para criar um aplicativo de linha de comandos que produza algumas tabelas informativas que podem ser acessadas através do menu do sistema.

Joe Lennon, Software developer, Core International

Joe Lennon photoJoe Lennon, 24 anos, é desenvolvedor de software em Cork, Irlanda. Autor do livro Beginning CouchDB da Apress (ainda não publicado), tem colaborado com o IBM developerWorks com diversos artigos técnicos e tutoriais. Em seu tempo livre, Joe gosta de jogar futebol, mexer em pequenos mecanismos e bater seus recordes em seu Xbox 360.



26/Mar/2010

Antes de começar

Este tutorial é direcionado a desenvolvedores que queiram aprender a armazenar dados no formato XML em um banco de dados, conectar-se ao DB2 a partir de um aplicativo Python e aprender a converter dados de arquivos CSV para documentos XML. Embora seja uma vantagem, não é necessário conhecimento prévio sobre o Python (você aprenderá a instalá-lo neste tutorial). Este tutorial pressupõe que você utiliza o sistema operacional Microsoft® Windows®, mas os códigos devem funcionar, sem modificações, em outras plataformas. Quando você terminar este tutorial, você terá as habilidades necessárias para criar aplicativos Python poderosos que podem se comunicar e interagir com um banco de dados IBM DB2 e aproveitar o poder oferecido pelo pureXML.

Sobre este tutorial

Acrônimos usados frequentemente

  • API: Application programming interface
  • CSV: Comma separated value
  • DBA: Database administrator
  • SQL: Structured Query Language
  • UI: User interface
  • URL: Uniform Resource Locator
  • XML: Extensible Markup Language

O sistema de gerenciamento de banco de dados DB2 da IBM tem tido um papel importante na área de gerenciamento de dados relacionais. Entretanto, em anos recentes, houve um aumento significativo nos requisitos para que as estruturas de dados sejam mais flexíveis e direcionadas ao próprio documento. Um dos exemplos mais notáveis dessas estruturas de dados é o XML.

Enquanto muitos sistemas de banco de dados relacional têm se apressado para incorporar algum tipo de suporte XML aos seus bancos de dados, o IBM DB2 é o único no mercado que permite o armazenamento nativo de XML em seu banco de dados, sem alterações e fiel ao seu formato original. Ele é conhecido como pureXML—, uma tecnologia que permite aos desenvolvedores DB2 e DBA a manipularem e relatarem dados XML ao lado de dados relacionais, sem afetar de maneira negativa a pureza do próprio XML.

Neste tutorial, você desenvolverá um script Python que se conecta ao Web site do United States Census Bureau e baixa um arquivo CSV contendo dados sobre a população em níveis nacionais, regionais ou estaduais—incluindo os resultados do Censo de 2000 e as variações com base em estimativas de cada ano seguinte. Você aprenderá a processar estes dados, convertendo-os para um documento XML. Ao invés de importar este grande documento e contar com as funções do DB2 para dividi-lo e jogá-lo em linhas individuais, você utilizará o Python para inserir estes dados no DB2, com um documento XML armazenado para cada linha relevante no arquivo CSV. Finalmente, você criará um aplicativo de linha de comandos que gerará relatórios úteis a respeito destes dados, mostrando uma lista de estados, regiões ou países classificados em ordem decrescente, de acordo com a população.

Pré-requisitos

Para seguir as etapas deste tutorial, é necessário possuir o seguinte software instalado:

  • IBM DB2 Express-C 9.5 ou superior
  • Python Version 2.6 ou qualquer versão anterior a 3.0

Consulte Recursos para ver os links para baixar esses pré-requisitos. Este tutorial pressupõe que você utiliza o sistema operacional Microsoft Windows, de preferência o XP ou superior. Para instalar o Python e a extensão IBM DB2 para Python, será necessário ter privilégios administrativos no seu computador.


Configurando o banco de dados do microblog

Nesta seção, você criará um novo banco de dados IBM DB2 utilizando o utilitário DB2 Command Editor antes de criar uma série de tabelas que armazenarão os dados populacionais do senso no formato XML. Você criará três tabelas: país, região e estado. Cada uma dessas tabelas armazenará um ID exclusivo para cada linha da tabela, assim como um documento XML que armazenará os dados do senso que serão importados dos arquivos CSV do U.S. Census Bureau posteriormente neste tutorial.

Criando o banco de dados

Vamos começar. Abra o DB2 Command Editor (Start>Programs>IBM DB2>[DB2 Instance Name]>Command Line Tools) e insira o seguinte comando: create database census using codeset UTF-8 territory US.

Esse processo pode levar um minuto ou mais até ser concluído, assim, seja paciente. Quando estiver concluído, você receberá uma mensagem de resposta parecida com: DB20000I The CREATE DATABASE command completed successfully.

Dica: Pode-se executar comandos rapidamente no Command Editor pressionando Ctrl+Enter.

Agora, conecte-se ao recém criado banco de dados do senso utilizando o seguinte: connect to census.

Novamente, você deverá receber uma resposta do servidor DB2. Dessa vez, algo parecido com: A JDBC connection to the target has succeeded.

Agora o banco de dados está criado e você está pronto para criar as tabelas que armazenarão os dados do aplicativo.

Criando as tabelas de banco de dados

Você carregará os dados populacionais no banco de dados e os armazenará em três tabelas separadas: país, região e estado. Vamos criar essas tabelas agora em Listagem 1.

Listagem 1. instruções SQL DDL para criar tabelas
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)
);

Cada uma dessas tabelas armazena o mesmo tipo de dados—um identificador exclusivo que será automaticamente gerado pelo DB2 cada vez que uma linha for inserida e uma coluna de dados XML que armazenará um documento XML para cada linha. Mais exatamente, pode-se usar uma única tabela aqui e criar um tipo de coluna nela para determinar se a linha é um país, uma região ou um estado, mas separá-las tornará a manipulação futura mais flexível.

Quando as instruções SQL acima são executadas, o DB2 deve dar as seguintes respostas de volta, para cada tabela: DB20000I. The SQL command completed successfully.

Com o banco de dados configurado, agora você está apto para instalar e configurar o Python e a extensão ibm_db para Python.


Instalando e configurando o Python

Python é uma linguagem de programação de alto nível com um grande foco na capacidade de leitura do código. Diferente de muitas outras linguagens de programação, nas quais a indentação e o estilo do código estão a critério do desenvolvedor, no Python, a indentação deve ser utilizada para designar blocos de código (tais como classes, instruções com o termo "if" e loops). O Python é de fácil aprendizagem, gera um código limpo e elegante e é largamente suportado em um host de diferentes plataformas, tornando-o uma excelente escolha para uma grande variedade de projetos de desenvolvimento de aplicativos.

Sobre o Python

Apesar de o Python geralmente vir pré-instalado nos sistemas operacionais Mac OS e Linux®, o mesmo não ocorre com o Microsoft Windows. Felizmente, o Python pode ser baixado e instalado no Windows—e você aprenderá como fazê-lo nesta seção. Entretanto, antes de começar, vale a pena mencionar que há um número de opções na hora de baixar o Python para Windows.

A primeira opção é utilizar o instalador binário de código aberto, disponível para download no Web site oficial da Python. Essa opção oferece a versão mais atualizada do Python e é fornecida com uma licença de código aberto. Neste tutorial, você trabalhará com essa versão do Python.

Como alternativa, o ActiveState Python comercial oferece alguns recursos adicionais, tais como a documentação completa e extensões Python adicionais, incluindo extensões específicas para Windows que facilitam o desenvolvimento de aplicativos baseados em Win32 API utilizando o Python.

Instalando o Python

O primeiro passo para a instalação do Python é baixá-lo do Web site oficial do Python (consulte Recursos para o link). Neste momento, as versões atuais do Python são 2.6.4 e 3.1.1. Este tutorial pressupõe que você esteja usando a versão 2.6* do Python. Como a versão 3.0 ou superior não é compatível com versões anteriores, recomenda-se que se baixe a última versão anterior à versão 3.0 (versão 2.x.x) oferecida para download. Salve este arquivo em sua unidade de disco rígido quando terminar o download, abra o arquivo .msi e inicie o programa de configuração.

Quando o instalador iniciar, ele lhe perguntará se você quer instalar para todos os usuários ou somente para você (esta opção não está disponível no Windows Vista®). Deixe a opção padrão selecionada, Install for all users, e pressione Next para continuar. Agora lhe será pedido para selecionar o diretório de destino. O diretório padrão deve ser C:\Python26\ ou similar; novamente, aceite este padrão e pressione Next para seguir em frente. Agora, você terá a oportunidade de customizar a instalação do Python selecionando quais recursos quer instalados. Como padrão, tudo está selecionado, então deixe desta maneira e pressione Next para iniciar a instalação. O processo levará uns dois minutos para ser completado e quando estiver concluído, você verá uma janela como esta na Figura 1.

Figura 1. Concluindo a janela do instalador do Python 2.6.4
Screen capture of Completing the Python 2.6.4 Installer window

Pressione Finish para sair do aplicativo de configuração. Antes de continuar, vale a pena verificar se o Python está instalado e funcionando corretamente. Se desejado, pode-se utilizar os atalhos que foram criados no Menu Iniciar do Windows, mas recomenda-se iniciar o Python pelo prompt de comandos já que é desta maneira que ele executará os scripts que você criará mais tarde neste tutorial.

Primeiro, abra a janela de prompt de comandos do Windows através da caixa de diálogos Executar (Iniciar>Executar, então, insira cmd) ou navegue até Iniciar>Programas>Acessórios>Prompt de Comando). No prompt, insira o comando: python.

Agora, você deverá estar no prompt do Python, indicado por >>>, como mostrado na Figura 2. (Consulte uma visualização somente em texto da Figura 2.)

Figura 2. Prompt do Python
Screen capture of Python prompt in the commandprompt window

Observação: Caso apareça uma mensagem do tipo python is not recognized as an internal or external command, operable program or batch file, o diretório do Python não foi colocado no Path do Windows. Consulte Recursos para informações de como configurá-lo. Para sair do prompt do Python, insira o seguinte comando: quit().

Você deve retornar ao prompt de comando do Windows após inserir esse comando no prompt do Python. Nesta seção, mostraremos como instalar a extensão ibm_db para Python, que lhe permitirá conectar-se ao banco de dados DB2 a partir do Python.

Instalando a extensão ibm_db para Python

A extensão ibm_db para Python lhe permite conectar-se e interagir com um banco de dados IBM DB2 utilizando código Python. Para instalar esta extensão, primeiramente será necessário instalar o utilitário easy_install (setuptools). Navegue pela página do pacote de setuptools (consulte Recursos e encontre o arquivo para a sua versão do Python, que é 2.6 neste caso). Baixe esse arquivo para a sua unidade de disco rígido, e quando estiver concluído, abra-o para instalar o aplicativo easy_install.exe no seu diretório de Scripts Python (geralmente C:\Python26\Scripts).

A instalação da extensão ibm_db, em si, é bem simples. Abra a janela de prompt de comando do Windows (Iniciar>Executar>cmd) e insira o seguinte comando, e caso o Python esteja instalado em um outro diretório, faça a modificação necessária: C:\Python26\Scripts\easy_install ibm_db.

Esse comando procurará, baixará, extrairá e instalará a extensão ibm_db automaticamente. Quando concluído, você será levado de volta ao prompt de comandos do Windows, como mostra a Figura 3. (Consulte uma visualização somente em texto da Figura 3.)

Figura 3. Instalação da extensão ibm_db concluída com sucesso
Screen capture of successfully installed ibm_db extension with 'Finished processing dependencies message

Em seguida, você verificará se a extensão ibm_db está funcionando corretamente, testando sua conexão com o banco de dados DB2 criado anteriormente neste tutorial.

Conectando-se ao DB2 a partir do Python

Com a criação do banco de dados DB2 e a instalação e configuração do Python e da extensão ibm_db, você agora está pronto para verificar se a conexão com o DB2 a partir do Python é possível. Abra o a janela do prompt de comandos do Windows e insira o comando python para iniciar o interpretador Python.

No prompt, insira os seguintes comandos para conectar-se ao DB2 e fazer a contagem do número de linhas na tabela de países. Observe que o prompt do Python (>>> e ...) foi incluído aqui meramente com objetivos ilustrativos e que você não deve digitá-los no interpretador. Certifique-se também de substituir as credenciais no código em Listagem 2com suas credenciais DB2 verdadeiras.

Listagem 2. Conexão do código Python ao DB2
>>> 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)
...

Após inserir a linha final acima, pressione enter para executar o código. Você deve obter (Count: 0) como mostra a Figura 4.

Figura 4. Resultado do teste de conexão DB2
Screen capture of the result of DB2 connection test

Caso surja algum problema ao conectar-se ao DB2 a partir do Python, verifique se as extensões ibm_db foram instaladas corretamente e se você já criou o banco de dados como descrito anteriormente neste tutorial. Também verifique se suas credenciais para conexão ao DB2 estão corretas.

Após concluir a configuração do banco de dados e o Python estiver funcionando, você está pronto para começar a desenvolver o assunto principal deste tutorial. Na próxima seção, você baixará, analisará e converterá dados CSV do U.S. Census Bureau e os salvará como dados XML no banco de dados DB2. Mostraremos como interpretar estes dados do banco de dados e exibi-los para o usuário.


Baixando e convertendo os dados CSV

Nesta seção do tutorial, mostraremos como criar um script Python para baixar um arquivo CSV do Web site do United States Census Bureau. Então, você processará estes dados CSV e os converterá para XML para que possam ser armazenados no banco de dados DB2 pureXML criado anteriormente neste tutorial.

Antes de iniciar, deve-se criar uma pasta em algum local do disco rígido onde você armazenará os arquivos do projeto. Eu armazenei meus dados na pasta C:\pycensus e sugiro que você faça o mesmo.

Baixando arquivos CSV do Web site do US Census Bureau

O United States Census Bureau possui uma superabundância de dados disponíveis para download, em uma variedade de formatos diferentes. Infelizmente, os dados populacionais do Censo de 2000 e as estimativas para cada ano seguinte só estão disponíveis no formato CSV e não em XML. Entretanto, isso não é um problema, já que você pode usar o Python para baixar esse arquivo CSV do Web site do Census Bureau e convertê-lo para XML que pode ser armazenado no banco de dados DB2 pureXML.

Se desejado, pode-se apontar seu navegador da Web para o URL para a pasta do projeto do arquivo CSV. Entretanto, ao invés disso, você criará um script Python que executará essa tarefa. Utilizando seu editor de texto preferido, crie um novo arquivo e salve-o como download.py na sua pasta do projeto (C:\pycensus, por exemplo). Adicione o código da Listagem 3 a esse arquivo.

Listagem 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()

Neste script, você utiliza o módulo httplib para se conectar ao Web site census.gov e emitir um pedido GET para o arquivo CSV necessário. Então, pegue a resposta e grave em um arquivo nomeado data.csv. Para executar este script, abra o Prompt de Comandos do Windows e altere o diretório do projeto para: cd \pycensus.

Então, execute o seguinte comando para executar o script Python: python download.py.

Quando o script estiver concluído você retornará ao prompt. Você pode se perguntar o porquê da ausência de mensagens—não se preocupe, é um bom sinal de que não ocorreu nenhum erro. Abra a pasta do projeto no Windows Explorer e observe que agora há um arquivo extra na pasta chamado data.csv. O Microsoft Excel® será o programa padrão para abrir este tipo de arquivo, caso você o tenha instalado. Ao abri-lo, você terá um resultado como o mostrado na Figura 5.

Figura 5. data.csv no Microsoft Excel
Screen capture of data.csv in Microsoft Excel

AVISO: NÃO salve este arquivo no Excel, pois ele pode modificar o formato do arquivo CSV da maneira que melhor se adeque ao programa, fazendo com que ele não seja legível pelo Python. Se o Excel lhe perguntar se quer salvar o arquivo, escolha Não. Caso salve este arquivo por acidente, simplesmente exclua-o e execute o script Python download.py novamente. Nesta seção, mostraremos como converter este arquivo CSV para um arquivo XML.

Convertendo dados CSV para documentos XML

Para converter dados CSV para XML, deve-se ter certeza de como se quer armazenar os dados: se registros distintos devem ser armazenados de maneira diferente e verificar se alguns registros devem ser descartados. No exemplo do arquivo CSV que você acabou de baixar, você notará que ele contém três tipos de dados: uma linha única de informações do país inteiro; quatro linhas para dados das regiões nordeste, meio oeste, sul e oeste; cinquenta e uma linhas para dados dos cinquenta estados dos EUA e o Distrito de Columbia; e uma linha para o Estado Livre Associado de Porto Rico. A primeira linha do arquivo é a linha de cabeçalho que será usada para os nomes das colunas.

O script criado nesta seção tomara como base a linha de cabeçalho e usará estes dados para formar os nomes de identificação de cada elemento que um registro deve possuir no documento XML. O script determinará, com base nas primeiras quatro colunas, se a linha em particular se refere a um país, região ou estado e designará um nome de identificação adequado para indicar a que o documento XML se refere. Finalmente, o script optará por excluir o Estado Livre Associado de Porto Rico por conter alguns dados incompletos.

Crie, em seu editor de texto, um novo arquivo e salve-o como convert.py. Adicione a esse arquivo o código da Listagem 4.

Listagem 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>"

Neste arquivo, a biblioteca csv será usada para ler o arquivo data.csv. Envolva os resultados com uma tag XML de abertura <data> e um de fechamento </data> já que um arquivo único de saída está sendo produzido. Então faça um loop em cada linha do arquivo CSV. Se a linha atual for a primeira linha do arquivo, coloque esse registro como cabeçalho. Ele será utilizado mais tarde no script como um nome de elemento para cada campo nos registros de país, região ou estado. Se a linha atual não for o registro de cabeçalho, faça um loop em cada coluna no registro e crie uma sequência interna de elementos XML cujo nome é acionado pelo registro de cabeçalho. Verifique então se a linha em questão está se referendo ao país, região ou estado e envolva o elemento XML interno em uma tag externa<country>, <region>, ou <state> adequada. Finalmente, verifique se o registro contém um X em um campo específico. Caso possua, defina um indicador de variáveis booleanas para True que interromperá a adição desta linha em particular ao documento XML. A maneira de executar esse script é a mesma de antes, emitindo: python convert.py.

Executando o script dessa maneira você gerará um resultado como o mostrado na Figura 6.

Figura 6. resultados convert.py
Screen capture of convert.py output, showing data information as concatenated XML document

Como se pode observar, o script colocou os dados diretamente na tela. Seria muito mais útil se esses dados fossem salvos em um arquivo. Ao invés de criar mais um código Python para fazer isso, pode-se simplesmente modificar o comando emitido para dizer ao prompt de comando para salvar os resultados em um arquivo com o nome de data.xml: python convert.py > data.xml.

Isso criará um novo arquivo no diretório do projeto com o nome de data.xml. Se este arquivo for aberto em um aplicativo de leitura e formatação XML, como o Firefox, pode-se observar um resultado como mostra a Figura 7.

Figura 7. Resultados XML no Mozilla Firefox
Screen capture of data viewed as XML output in Mozilla Firefox

Com os dados armazenados em um arquivo como este, pode-se importar o XML para o banco de dados DB2 utilizando um arquivo .del e o comando IMPORT. Entretanto, esses resultados desses dados XML são armazenados em uma linha única na tabela DB2. Agora, é possível utilizar o XQuery para dividir esses dados e armazená-los em linhas separadas. Mas como o Python já está sendo usado para criar o documento XML, é muito mais fácil executar uma série de instruções INSERT diretamente no próprio script convert.py. Na próxima seção, mostraremos como fazer isso modificando o script convert.py.


Salvando o arquivo XML no DB2 com o Python

Foi mostrado anteriormente como formatar os dados CSV que foram baixados do U.S. Census Bureau para um arquivo XML grande. Agora será mostrado como inserir as linhas de país, regiões e estados no banco de dados DB2. Faça as alterações listadas nesta seção para converter o arquivo convert.py criado na seção anterior.

Incluindo a biblioteca ibm_db

A primeira coisa que se deve fazer é incluir a biblioteca ibm_db em seu código. Para fazer isso, modifique a primeira linha do arquivo convert.py para: import csv, ibm_db.

Como esse script assim, ele faz com que cada linha seja inserida repetidamente ao ser executado, resultando em uma grande quantidade de dados duplicados. Para evitar que isso aconteça, limpe as tabelas do banco de dados no início do script para que cada vez que ele seja executado, ele comece do zero. Adicione a Listagem 5 bem abaixo da instrução de importação da Listagem 4, que acabou de ser modificada (em outras palavras, antes da linha reader = csv.reader... na Listagem 4).

Listagem 5. Extrato de convert.py—limpeza das tabelas
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."

Você deve-se lembrar do código para conectar-se ao banco de dados DB2 de uma seção anterior deste tutorial, onde foi mostrado como testar o funcionamento da conexão do Python com o DB2. Agora, você estará executando três instruções SQL—deletando todos os dados das tabelas do país, região e estado, respectivamente. Nesse caso, o Python emitirá uma mensagem confirmando que a instrução foi executada com sucesso ou se ocorreu um erro. Caso ocorra algum erro, a mensagem de erro do DB2 é transmitida ao usuário, tornando mais fácil sua depuração.

A seguir, será necessário excluir duas instruções de impressão resultantes da declaração XML do arquivo único e grande criado na seção anterior. São elas: print "<data>" e print "</data>".

A primeira deve estar bem abaixo da linha reader = csv.reader..., e a última deve estar na última linha do arquivo.

Finalmente, será necessário alterar o arquivo convert.py para que ele não imprima o código XML para cada linha e que, ao invés disso, salve-o como um documento XML na tabela DB2 apropriada. Você já criou um código para determinar se uma linha em particular é um país, região ou estado e para gerar um XML para cada linha; agora é preciso criar uma instrução relevante INSERT e executá-la.

Encontre a linha que possui print xml. Será necessário substituir essa linha com o código da Listagem 6. Tenha em mente que o Python é muito sensível no que diz respeito à indentação do código, então, certifique-se de que o código tenha sido disposto corretamente no editor de texto.

Listagem 6. Extrato de convert.py—salvando as linhas no banco de dados 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

O código final para o convert.py deve se parecer com a Listagem 7. Novamente, a indentação tem um papel muito importante no Python, então, certifique-se de que ela está correta ou pode-se obter resultados inesperados.

Listagem 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

Certifique-se de ter salvo este arquivo e abra o prompt de comandos do Windows. Altere o diretório do projeto e execute o script convert.py novamente, desta vez utilizando o seguinte comando (não canalize o resultado para um arquivo): python convert.py.

Deve-se lembrar do número de mensagens "Row added to state table" que aparecem uma atrás da outra, como mostra a Figura 8.

Figura 8. Resultado convert.py
Screen capture of output from revised convert.py

Antes de ler os dados do DB2 utilizando o Python, abra o DB2 Command Editor e verifique como esses dados aparecem no banco de dados. Certifique-se de que está conectado ao banco de dados do senso (emita o comando connect to census se necessário) e insira a seguinte instrução SQL: select * from state. Essa consulta deve gerar 51 resultados, como mostra a Figura 9.

Figura 9. Visualização dos Resultados da Consulta
Screen capture of Query Results view with numbered XML data entries

Clique no botão more (...) próximo a cada uma das linhas na guia dos resultados da consulta. Isso abrirá o XML Document Viewer, mostrando o documento XML associado àquela linha em particular. Deve-se obter uma tela parecida com a da Figura 10.

Figura 10. XML Document Viewer
Screen capture of an XML document in the Tree View tab in the XML document viewer

Sinta-se a vontade para executar uma instrução SQL similar para recuperar as tabelas do país e da região; deve-se obter uma linha única de resultado para a tabela de país e quatro linhas para a tabela de regiões.

A seguir, mostraremos como ler os dados do DB2 no Python e apresentá-los ao usuário.

Lendo XML a partir do DB com Python

Nesta seção, mostraremos como construir um aplicativo de linha de comandos Python que pedirá que o usuário escolha uma de três opções de menu. Essas opções permitirão que o usuário visualize a lista de estados, regiões ou países ordenada por "população" e retirada do censo de 2000.

Para iniciar, conecte-se ao banco de dados DB2, imprima a lista de opções do menu e peça para que o usuário escolha. Crie um novo arquivo com o nome de read.py e adicione a ele o código da Listagem 8.

Listagem 8. Extrato do arquivo read.py—início
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

Na Listagem 8, deve-se, primeiro, importar o ibm_db e as bibliotecas locais. As bibliotecas locais são necessárias para formatar o número da população para que ele seja mais legível (utilizando separadores para os milhares). Você iniciará o aplicativo definindo o local como configuração padrão em sua máquina. A seguir, conecte-se ao banco de dados DB2 antes de imprimir as informações a respeito das diferentes opções do menu que estão disponíveis para o usuário.

A seção final do código na Listagem 8 requer que o usuário insira um valor e verifica se ele é um número inteiro e se é uma das quatro opções disponíveis —1, 2, 3 ou 4. Se o valor fornecido não for um desses quatro valores, ele continuará pedindo um valor até que seja inserido um número válido. O usuário pode sair do programa a qualquer momento, selecionando a opção 4.

Agora que o aplicativo determinou que dados o usuário deseja visualizar, ele deve criar uma instrução SQL apropriada para recuperar esses dados. O código na Listagem 9 faz exatamente isso.

Listagem 9. Extrato do arquivo read.py—criando o 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()

Na Listagem 9, o bloco "if" verifica se valor inserido pelo usuário foi 1, 2, 3 ou 4. Se ele detectar um valor entre 1 e 3, ele criará uma instrução SQL para visualizar os dados populacionais por estados, regiões e países. Ele sairá do programa caso detecte que o número 4 foi inserido.

A instrução SQL para cada opção é virtualmente a mesma, exceto pelo fato de focar em uma tabela diferente a cada instância. Basicamente, ela utiliza a função XMLTABLE para mapear os elementos XML na coluna de dados da tabela para diferentes colunas de estilo relacionais. Ela então coloca os dados em ordem decrescente de acordo com o valor da população.

A parte final do aplicativo está executando a instrução SQL e fazendo o loop pelo resultado definido para gerar uma tabela de resultados. Listagem 10 mostra esse código.

Listagem 10. Extrato do arquivo read.py—Formatando os resultados
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 "'----------------------------------------------'"

Neste código, você executará a instrução SQL que foi gerada pelo código na Listagem 9, e imprimirá uma tabela que formata bem os resultados. Nesta seção, você está usando uma série de funções Python que executam manipulações de cadeia de caractere, tais como justificar à esquerda, centralizar e justificar o texto à direita e formatar o valor populacional com separadores de milhares para tornar a leitura mais fácil.

Com o código completo para a leitura desse banco de dados, você está pronto para executar o script. No Prompt de Comandos do Windows, certifique-se de que está no diretório do projeto e utilize o seguinte comando para iniciar o programa: python read.py.

Quando o programa executar, ele se conectará ao DB2 e lhe apresentará a seguinte lista de opções de menu que podem ser inseridas nesse aplicativo:

  1. Lista de estados por população
  2. Lista de regiões por população
  3. Lista de países por população
  4. Sair do aplicativo

Figura 11 mostra o menu de opções. (Consulte uma visualização somente em texto da Figura 11.)

Figura 11. Menu do aplicativo
Screen capture of the application menu with four menu options

Tente inserir uma opção de menu inválida como, por exemplo, a cadeia de caractere hello. Você receberá uma mensagem de erro como mostra a Figura 12, antes que lhe seja pedido para inserir a opção novamente. (Consulte uma visualização somente em texto da Figura 12.)

Figure 12. Erro de opção inválida de menu
Screen capture of invalid menu option error

Desta vez, insira uma opção válida. Foi selecionada a opção 2 (Lista de regiões por população). Essa opção deve gerar um resultado como mostra a Figura 13. (Consulte uma visualização somente em texto da Figura 13.)

Figure 13. Dados populacionais regionais
Screen capture of regional population data

Como pode ser visto, o aplicativo apresenta uma tabela com uma lista de regiões, com a região com o maior número de habitantes mostrada primeiro. Deve-se observar um resultado similar para as duas outras opções de menu, exceto que a opção 1 mostrará 51 estados e a opção 3 mostrará somente um país.

Experimente as diferentes opções de menu e tente melhorar o aplicativo adicionando mais opções e diferentes modos de visualização dos dados.


Resumo

Neste tutorial, mostramos como criar um banco de dados DB2 que inclua tabelas com colunas de dados XML nativos. Então mostramos como instalar o Python e as extensões ibm_db para Python através do utilitário easy_install. A seguir, você pode verificar que é possível comunicar-se com o banco de dados DB2 a partir do interpretador Python. Você, então, desenvolveu um script Python que baixou os dados populacionais do Web site do U.S. Census Bureau antes de converter estes dados CSV para o formato XML e salvá-los em tabelas DB2. Finalmente, você criou um aplicativo básico de linhas de comandos que forneceu relatórios no formato de tabelas sobre os dados populacionais nacionais, regionais e estaduais.

Com as informações fornecidas neste tutorial, deve-se ter o conhecimento necessário para melhorar suas habilidades de desenvolvimento Python e DB2.


Download

DescriçãoNomeTamanho
Python CSV source codepython.csv.source.zip3KB

Recursos

Aprender

Obter produtos e tecnologias

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre, Information Management
ArticleID=477983
ArticleTitle=Manipule dados CSV com o Python e o pureXML
publish-date=03262010