Pular para o conteúdo. Ir para a navegação
Ações do site
Opções do usuário

TcheZope.org

Você está aqui: Página Inicial Documentação Manuais O Livro do Zope Conectividade de Banco de Dados Relacionais
Ações do documento

13. Conectividade de Banco de Dados Relacionais

Um nível acima
Este capítulo descreve como o Zope se conecta a banco de dados relacionais externos. Mostra a você como se conectar e fazer buscas a um banco de dados. Também mostra as características que permitem a você criar dados relacionais como se estivesse usando objetos do Zope. Enfim, o capítulo mostra considerações de segurança e performance.

O Zope usa um banco de dados objeto para armazenar objetos do Zope. Bancos de dados relacionais tais como Oracle, Sybase e PostgreSQL armazenar informações de modos diferentes. Bancos de dados relacionais armazenam suas informações em tabelas, como mostra a Figura 10.1.

10-1.png

Figura 10.1 - Tabela de Banco de Dados Relacional

A informação na tabela é armazenada em linhas. O layout das colunas da tabela é chamado de esquema. Uma linguagem padrão, chamada Structured Query Language (SQL - Linguagem de Busca Estruturada), é utilizada para consultar e alterar tabelas em bancos de dados relacionais.

O Zope não armazena suas informações dessa forma. O banco de dados objeto do Zope permite muitos tipos diferentes de objetos que têm muitos tipos diferentes de relacionamentos uns com os outros. Dados relacionais não são facilmente mapeados em objetos uma vez que dados relacionais assumem um modelo de dados orientado à tabelas muito mais simples. O Zope fornece vários mecanismos para obtenção de dados relacionais e para usá-los no mundo dos objetos do Zope, incluindo Database Adapters e SQL Methods que discutiremos detalhadamente neste capítulo.

O uso mais comum para o suporte à banco de dados relacionais do Zope é para colocar bancos de dados relacionais existentes na web. Por exemplo, suponha que o seu Departamento de Recursos Humanos tenha um banco de dados de empregados. Seu banco de dados vem com ferramentas para permitir os administradores rodarem relatórios e alterarem dados. Entretanto, é difícil para os empregados verem seus próprios registros e fazerem uma simples manutenção, como uma atualização no seu endereço quando eles se mudam. Através do interfaceamento do seu banco de dados relacional com o Zope, seus empregados podem usar qualquer web browser para ver e atualizar seus registros do escritório ou de casa.

Usando o seu banco de dados relacional com Zope você obtém todos os benefícios do Zope, incluindo segurança, apresentação dinâmica, serviços de rede, e mais. Você pode usar Zope para modelar dinamicamente seu acesso aos dados, apresentação de dados, e administração de dados.

Para usar banco de dados relacional no Zope você deve criar dois diferentes objetos do Zope, um Database Connection e um Z SQL Method. A Conexão de Banco de Dados diz ao Zope como conectar com um banco de dados relacional. O Método Z SQL descreve uma ação para consulta em um banco de dados. O Método Z SQL utiliza a Conexão de Banco de Dados para conectar-se com o banco de dados relacional. Nós veremos mais de perto esses dois tipos de objetos nesse capítulo.

Usando Conexões de Banco de Dados

Conexões de Banco de Dados são utilizadas para estabelecer e administrar conexões com bancos de dados relacionais externos. Conexões de Banco de Dados devem ser estabelecidas antes que os métodos de banco de dados possam ser definidos. Outrossim, todo Método Z SQL deve ser associado com uma conexão de banco de dados. Adaptadores de banco de dados (ou DAs, para abreviar) estão disponíveis para os seguintes bancos de dados:

Oracle

Oracle é um banco de dados relacional comercial popular e poderoso. Este DA é escrito e tem suporte comercial por parte da Zope Corporation. Oracle pode ser adquirido ou avaliado no web site da Oracle.

Sybase

O Sybase é outro banco de dados relacional comercial popular. O Sybase DA é escrito e tem suporte comercial por parte da Zope Corporation. Sybase pode ser adquirido ou avaliado no web site da Sybase.

ODBC

ODBC é um protocolo padrão da indústria, independente de plataforma, código fonte aberto, suportado por muitos bancos de dados comerciais. O DA ODBC é escrito e tem suporte comercial por parte da Zope Corporation.

PostgreSQL

PostgreSQL é um banco de dados relacional de fonte aberto líder. Há vários adaptadores de banco de dados para o PostgreSQL, incluindo ZpoPy, que é mantido pelo membro da comunidade do Zope Thierry Michel. Você pode encontrar mais informação sobre PostgreSQL no web site do PostgreSQL.

MySQL

MySQL é um banco de dados relacional rápido de fonte aberto. Você pode encontrar mais informação sobre MySQL no web site do MySQL. O DA MySQL é mantido pelo membro da comunidade Zope Monty Taylor.

Interbase

Interbase é um banco de dados relacional de fonte aberto da Borland/Inprise. Você pode encontrar mais informação sobre Interbase no web site da Borland. Você pode também ficar interessado no FireBird, que é uma comunidade mantida no ramo do Interbase. O adaptador Interbase do Zope é mantido pelo membro da comunidade Zope Bob Tierney.

Gadfly

Gadfly é um banco de dados relacional escrito em Python por Aaron Waters. Gadfly está incluso com o Zope para propósitos de demonstração e pequenos conjuntos de dados. Gadfly é rápido, mas não é significativo para grandes quantias de informação, uma vez que lê o banco de dados inteiro dentro da memória. Você pode descobrir mais sobre Gadfly no web site da Chordate.

Com excessão do Gadfly, todos os bancos de dados relacionais rodam como processos externos ao Zope. Na verdade, seu banco de dados relacional não necessita rodar sempre na mesma máquina que o Zope, pois o Zope pode conectar-se à máquina na qual o banco de dados está rodando. Instalar e configurar bancos de dados relacionais está além do escopo deste livro. Todos os bancos de dados relacionais mancionados têm sua própria documentação de instalação e configuração, que você deveria consultar para detalhes específicos.

Devido ao Gadfly rodar dentro do Zope, você não necessita especificar qualquer informação de conexão para o Zope encontrar o banco de dados. Uma vez que todos os outros tipos de bancos de dados rodam externamente ao Zope, eles requerem que você especifique como conectar-se ao banco de dados. Esta especificação, chamada de connection string, é diferente para cada tipo de banco de dados. A Figura 10.2, por exemplo, mostra o formulário de adição da conexão do banco de dados do PostgreSQL.

10-2.png

Figura 10.2 - Conexão do Banco de Dados PostgreSQL

Para o PostgreSQL, o formato de string de conexão é mostrado acima na Figura 10.2.

Para usar o banco de dados relacional de sua escolha através do Zope, você deve fazer o download e instalar o adaptador de banco de dados para o seu banco de dados relacional específico. Adaptadores de banco de dados podem ser baixados da sessão Products do Zope.org. A exceção para isto é o Gadfly, que está incluso com o Zope. Todos os exemplos neste capítulo usam Gadfly, mas os procedimentos descritos aplicam-se para todos os bancos de dados.

Após ter instalado o produto adaptador para o seu banco de dados, você pode criar uma nova conexão de banco de dados selecionando-a em Add List. Todas as conexões de banco de dados são bastante parecidas. Selecione o Z Gadfly Database Connection da Lista de adição. Isso levará você para o formulário de adição para uma conexão de banco de dados Gadfly.

Selecione o data source (fonte de dados) Demo, especifique Gadfly_database_connection para o id, e clique no botão Add. Isso criará uma nova conexão de banco de dados Gadfly. Selecione a nova conexão clicando nela.

Você está olhando a aba Status da conexão com o banco de dados Gadfly (Gadfly Database Connection). Essa aba diz à você se você está conectado ou desconectado com o banco de dados, e tem um botão para conectar ou desconectar. No geral o Zope administrará a conexão com o seu banco de dados para você, então existem poucas razões para controlar manualmente a conexão. Para o Gadfly, conectar e desconectar não tem sentido, mas para bancos de dados esternos você pode querer conectar ou desonectar manualmente para fazer manutenção no banco de dados.

A próxima aba é a Properties. Essa aba mostra à você o datasource (a fonte de dados) e outras propriedades da conexão com o banco de dados. Isso é útil se você quiser mover a sua conexão de banco de dados de um datasource para outro. A figura 10.3 mostra a aba Properties.

10-3.png

Figura 10.3 - A aba Properties.

Você pode testar sua conexão a um banco de dados indo para a aba Test. Essa aba permite que você digite código SQL diretamente e o execute em seu banco de dados. Essa aba é apenas para testar seu banco de dados e emitir comandos SQL (como criação de tabelas). Esse não é o local onde você entrará com a maior parte de seu código SQL. Os comandos SQL estão nos métodos Z SQL que são discutidos mais tarde nesse capítulo.

Vamos criar uma tabela em seu banco de dados para usar nos exemplos desse capítulo. A aba Test da conexão com o banco de dados permite você enviar sentenças SQL diretamente para o seu banco de dados. Você pode criar tabelas digitando código SQL diretamente na aba Test; não há necessidade de usar um SQL Method para criar tabelas. Crie uma tabela chamada employees com o seguinte código SQL:

  CREATE TABLE employees 

(
emp_id integer,

first varchar,

last varchar,

salary float
)

Clique no botão Submit Query para rodar o commando SQL. O Zope deve retornar uma tela de confirmação que diz à você o quê o código SQL rodou e o resultado, se houver algum.

A SQL usada aqui pode diferir dependendo do seu banco de dados. Para detalhes exatos de criação de tabelas com seu banco de dados, consulte a documentação específica do usuário do banco de dados.

Essa SQL criará uma nova tabela em seu banco de dados Gadfly, chamada employees. Essa tabela terá quatro colunas, emp_id, first, last e salary. A primeira coluna é a identificação do empregado, que é um único número que identifica o empregado. As próximas duas colunas tem tipo varchar que é similar à uma string. A coluna salary tem tipo float que suporta números de ponto flutuante. Todos os bancos de dados suportam espécies de tipos, então, consulte sua documentação para achar que espécies de tipos seu banco de dados suporta.

Para garantir que a identificação do empregado é um único número você pode criar um índice em sua tabela. Digite o seguinte código SQL na aba Test:

  CREATE UNIQUE INDEX emp_id ON employees

(
emp_id
)

Agora você tem uma tabela e um ídice. Para examinar sua tabela, vá para a aba Browse. Esta aba deixa você ver as tabelas de seu banco de dados e seus esquemas. Aqui, você pode ver que há uma tabela employees, e se você clicar no símbolo de mais, (+) a tabela expande para mostrar quatro colunas, emp_id, first, last e salary como mostra a Figura 10.4.

10-4.png

Figura 10.4 - Navegando na Conexão do banco de dados

Esta informação é muito útil quando se cria aplicações SQL complexas, com muitas tabelas grandes que deixa você ver os esquemas de suas tabelas. Nem todos os bancos de dados suportam navegação em tabelas.

Agora que você criou uma conexão de banco de dados e tem definida uma tabela, você pode criar Z SQL Methods para operar em seu banco de dados.

Usando Métodos Z SQL

Os Z SQL Methods são objetos do Zope que executam código SQL através de uma Conexão de Banco de Dados. Todos os Métodos Z SQL devem ser associados com uma Conexão de Banco de Dados. Z SQL Methods podem tanto consultar bancos de dados quanto alterar dados. Z SQL Methods podem também conter mais que um comando SQL.

Primeiro, você precisa criar um novo Z SQL Method chamado hire_employee que insere um novo empregado na tabela employees. Quando um novo empregado é admitido, este método é chamado e um novo registro é inserido na tabela employees que contém as informações sobre o novo empregado. Selecione Z SQL Method da Add List. Isto leverá você ao formulário de adição de Z SQL Methods, como mostra a Figura 10.5.

10-5.png

Figura 10.5 - O formulário de adição para Z SQL Methods.

Como sempre, você deve especificar um id e um title para o Z SQL Method. Além disso, você precisa selecionar uma Conexão de Banco de Dados para usar com este Z SQL Method. Dê à este novo método o id hire_employee e selecione a Gadfly_database_connection que você criou na última seção.

Em seguida, você pode especificar argumentos para o Z SQL Method. Assim como Scripts, Z SQL Methods podem ter argumentos. Argumentos são utilizados para construir expressões SQL. Neste caso seu método necessita quatro argumentos, o número de identificação do empregado, o primeiro nome, o último nome e salário do empregado. Degite "emp_id first last salary" no campo Arguments. Você pode colocar cada argumento em sua própria linha, ou você pode colocar mais de um argumento na mesma linha separados por espaços. Você pode também fornecer valores padrões para argumentos como mos Scripts Python. Por exemplo, emp_id = 100 dá ao argumento do emp_id um valor padrão de 100.

O último campo do formulário é o Query template. Esse campo contém o código SQL que é executado quando o Z SQL Method é chamado. Neste campo, entre com o seguinte código:

  insert into employees (emp_id, first, last,salary) values
(<dtml-sqlvar emp_id type="int">,
<dtml-sqlvar first type="string">,
<dtml-sqlvar last type="string">,
<dtml-sqlvar salary type="float">
)

Note que este código SQL também contém DTML. O código do DTML neste modelo é utilizado para inserir os valores dos argumentos dentro do código SQL que será executado em seu banco de dados. Assim, se o argumento emp_id teve o valor 42, o argumento first teve o valor Bob e o seu argumento last teve o valor Uncle e o argumento salary teve o valor 50000.00 então o modelo de query poderia criar o seguinte código SQL:

  Insert into employees (emp_id, first, last, salary) values 
(42,
'Bob',
'Uncle',
50000.00
)

O modelo de query e SQL – especificamente tags DTML são explicadas melhor na próxima seção.

Você tem à sua escolha três botões para clicar para adicionar seu novo Z SQL Method. O botão Add criará o método e levará você de volta para o folder contendo o novo método. O botão Add and Edit criará o método e o fará o objeto correntemente selecionado no Workspace. O botão Add and Test criará o método que levará você a aba Test do método então você pode testar o novo método. Para adicionar seu novo Z SQL Method, clique o botão Add.

Agora você tem um Z SQL Method que insere novos empregados na tabela employees. Você necessitará outro Z SQL Method para consultar a tabela de empregados. Crie um novo Z SQL Method com o id list_all_employees. Ele não deveria ter nenhum argumento e conter o código SQL:

select * from employees

Este simples código SQL seleciona todo as linhas da tabela employees. Agora você tem dois Z SQL Methods, um para inserir novos empregados e um para ver todos os empregados no banco de dados. Vamos testar seus dois novos métodos inserindo alguns novos empregados na tabela employees e depois listando-os. Para fazer isto, clique no método hire_employees e clique na aba Test. Isto levará você para a aba Test do método, como mostra a Figura 10.6.

10-6.png

Figura 10.6 - A aba Test do hire_employee.

Aqui, você vê um formulário com quatro caixas de entrada, uma para cada argumento para o Z SQL Method hire_employee. O Zope gera automaticamente este formulário para você baseado nos argumentos de seu Z SQL Method. Pelo fato do Método hire_employee ter quatro argumentos, o Zope cria este formulário com quatro caixas de entrada. Você pode testar este método entrando com um número de empregado, um primeiro nome, um último nome, e um salário para seu novo empregado. Entre com o id do empregado "42", "Bob" para o primeiro nome, "McBob" para o último nome e um salário de "50000.00". Então clique o botão Test. Você verá então os resultados de seu teste.

A tela diz This statement returned no results. Isto é porque o método hire_employee apenas insere nova informação na tabela, isto não seleciona qualquer informação fora da tabela, assim não retornaram registros. A tela também mostra à você como o modelo de query é renderizada no SQL. Como esperado, as tags do DTML sqlvar renderizaram os quatro argumentos dentro do código válido da SQL que seu banco de dados executou. Você pode adicionar tantos empregados quanto você quiser testando repetidamente este método.

Para verificar que a informação que você adicionou está sendo inserida dentro da tabela, selecione o Z SQL Method list_all_employees e clique em sua aba Test.

Esta visão diz This query requires no input, indicando que o list_all_employees não tem qualquer argumento e assim, não requer entrada para executar. Clique no botão Submit Query para testar o método.

O método list_all_employees retorna os conteúdos de sua tabela employees. Você pode ver todos os novos empregados que você adicionou. O Zope automaticamente gera esta tela de relatório com tabela para você. Em seguida nós mostraremos como você pode criar sua própria interface de usuário para seus Z SQL Methods para integrá-los dentro do seu web site.

Chamando Métodos Z SQL

A pesquisa a um banco de dados relacional retorna uma sequência de resultados. Os itens na sequência são chamados de linhas de resultado. Resultados de pesquisas em SQL são sempre uma sequência. Até mesmo se a pesquisa da SQL retorna somente uma linha, aquela linha é o único item contido na lista de resultados. Portanto, Z SQL Methods sempre retornam uma sequência de resultados que contêm zero ou mais registros como resultado.

Os itens na sequência de resultados retornados por um Z SQL Method são chamados Result objects. Result objects podem ser como as linhas da tabela do banco de dados transformadas em objetos do Zope. Estes objetos têm atributos que ligam o esquema dos resultados do banco de dados.

Uma diferença importante entre result objects (objetos resultantes) e outros objetos do Zope é que os objetos resultantes não foram criados e permanentemente adicionados ao Zope. Objetos resultantes não são persistenes. Eles existem apenas por um curto período de tempo; tempo suficiente para você usá-lo em uma página de resultado ou para usar seus dados para algum outro objetivo. Com o request eles vão embora, e a próxima vez que você chamar um Z SQL Method você obtém um novo conjunto de novos objetos resultantes.

Objetos resultantes podem ser usados do DTML para mostrar os resultados da chamada de um Z SQL Method. Por exemplo, adicione um novo DTML Method ao seu site chamado listEmployees com o seguinte conteúdo DTML:

  <dtml-var standard_html_header>

<ul>
<dtml-in list_all_employees>
<li><dtml-var emp_id>: <dtml-var last>, <dtml-var first>
makes <dtml-var salary fmt=dollars-and-cents> a year.
</li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

Este método chama o Z SQL Method list_all_employees do DTML. A tag in é usada para interagir sobre o objeto eachResult retornado pelo Z SQL Method list_all_employees. Z SQL Methods sempre retornam uma lista de objetos, assim você irá quase sempre usá-los da tag DTML in a menos que você não esteja interessado nos resultados ou se o código SQL nunca retornará nenhum resultado, como hire_employee.

O corpo da tag in é um modelo que define o que é renderizado para cada objeto resultante na sequência retornada pelo list_all_employees. No caso de uma tabela com três empregados, listEmployees deveria retornar o seguinte HTML:

  <html>
<body>

<ul>
<li>42: Roberts, Bob
makes $50,000 a year.
</li>
<li>101: leCat, Cheeta
makes $100,000 a year.
</li>
<li>99: Junglewoman, Jane
makes $100,001 a year.
</li>
</ul>

</body>
</html>

A tag in renderiza uma lista de itens HTML para cada objeto resultante retornado pelo list_all_employees.

Depois veremos como criar interfaces de usuário para coletar dados e passá-los para Z SQL Methods.

Fornecendo Argumentos para Métodos Z SQL

No outro tópico, você teve aprendeu a mostrar empregados com o DTML Method listEmployees que chama o Z SQL Method list_all_employees. Agora vamos ver como construir uma interface de usuário para o Z SQL Method hire_employee. Lembre-se que hire_employee aceita quatro argumentos, emp_id, first, last, e salary. A aba Test no método hire_employee faz com que você chame este método, mas isto não é muito útil para integração em uma aplicação web. Você precisa criar seu próprio formulário de entrada de dados para seu Z SQL Method ou chamá-lo manualmente de sua aplicação.

A Z Search Interface pode criar um formulário de entrada de dados para você automaticamente. No Capítulo 11, "Pesquisando e Categorizando Conteúdo", você usou a Z Search Interface para construir um par form/action (formulário/ação) de métodos que automaticamente geraram um formulário HTML de busca e a tela de relatório que pesquisou o Catálogo e retornou resultados. A Z Search Interface também trabalha com Z SQL Methods para contruir um conjunto parecido de telas search/result (busca/resultado).

Selecione Z Search Interface da lista de adição e especifique hire_employee como o objeto a ser buscado. Entre com o valor "hireEmployee" para o Report Id e "hireEmployeeForm" para o Search Id de clique Add.

Clique no hireEmployeeForm criado recentemente e clique na aba View. Entre com um employee_id, um primeiro nome, um último nome, e salário para um novo empregado e clique em Submit. O Zope retorna uma tela que diz "There was no data matching this query". Porque o formulário de relatório gerado pela Z Search Interface tem objetivo de mostrar o resultado de um Z SQL Method, e o Z SQl Method hire_employee não retorna nenhum resultado; ele apenas insere uma nova linha na tabela. Edite o DTML Method hireEmployee um pouco para que fique mais informativo. Selecione o Method hireEmployee. Ele deveria conter o seguinte trecho DTML:

  <dtml-var standard_html_header>

<dtml-in hire_employee size=50 start=query_start>

<dtml-if sequence-start>

<dtml-if previous-sequence>

<a href="<dtml-var URL><dtml-var sequence-query
>query_start=<dtml-var
previous-sequence-start-number>">
(Previous <dtml-var previous-sequence-size> results)
</a>

</dtml-if previous-sequence>

<table border>
<tr>
</tr>

</dtml-if sequence-start>

<tr>
</tr>

<dtml-sequence-end>

</table>
<dtml-if next-sequence>

<a href="<dtml-var URL><dtml-var sequence-query
>query_start=<dtml-var
next-sequence-start-number>">
(Next <dtml-var next-sequence-size> results)
</a>

</dtml-if next-sequence>

</dtml-if sequence-;end>

<dtml-else>

There was no data matching this <dtml-var title_or_id> query.

</dtml-in>

<dtml-var standard_html_footer>

Este é um pedaço bem grande do DTML! Todo este DTML é para construir dinamicamente um formulário de resultado em forma de tabela em série. Já que não precisamos deste, vamos mudar o método hireEmployee para que seja bem mais simples:

  <dtml-var standard_html_header>

<dtml-call hire_employee>

<h1>Employee <dtml-var first> <dtml-var last> was Hired!</h1>

<p><a href="listEmployees">List Employees</a></p>

<p><a href="hireEmployeeForm">Back to hiring</a></p>

<dtml-var standard_html_footer>

Agora visualize hireEmployeeForm e coloque um novo empregado. Observe como o método hire_employee é chamado da tag DTML call. Isto é porque sabemos que não há saídas no método hire_employee. Já que não há resultados para interagir, o método não precisa ser chamado com a tag in. Ele pode ser simplesmente chamado com a tag call.

Agora você tem uma interface de usuário completa para inserir novos empregados. Usando o sistema de segurança do Zope, você pode agora restringir acesso a este método para um único grupo de usuários que tem permissão de inserir novos empregados. Lembre-se sempre telas de pesquisa e relatório geradas pela Z Search Interface são apenas ajudas que você pode facilmente adaptar para suas necessidades.

Depois daremos uma olhada mais de perto no controle preciso das buscas SQL. Você já viu como Z SQL Methods lhe permitem criar modelos básicos de buscas SQL. Na próxima seção você aprenderá como fazer a maioria dos seus modelos de busca.

Pesquisas Dinâmicas com SQL

Um modelo de busca com Z SQL Method pode conter DTML que é avaliada quando o método é chamado. Este DTML pode ser usado para modificar o código SQL que é executado pelo banco de dados relacional. Várias SQL especificam tags DTML existentes para ajudar você na construção de buscas complexas em SQL. Nas próximas seções você aprenderá sobre tags sqlvar, sqltest, e sqlgroup.

Inserindo Argumentos com a Tag Sqlvar

É muito importante ter certeza que você inseriu o tipo certo de dados dentro de uma coluna em um banco de dados. Seu banco de dados vai reclamar se você tentar usar a string "12" onde o inteiro 12 for esperado. SQL requer que diferentes tipos sejam especificados diferentemente. Para piorar, diferentes bancos de dados têm diferentes regras de especificação.

Além disso, para evitar erros, a especificação da SQL é importante para a segurança. Suponha que você tinha uma busca que faz um select:

  select * from employees
where emp_id=<dtml-var emp_id>

Esta busca não é segura até que alguém possa colocar o código SQL dentro da sua busca entrando com algo como 12; deixa a tabela empregados com um emp_id. Para evitar este problema você precisa certificar-se que suas variáveis foram propriamente especificadas. A tag sqlvar faz isto para você. Aqui está uma versão segura da busca acima que usa sqlvar:

  select * from employees
where emp_id=<dtml-sqlvar emp_id type=int>

A tag sqlvar funciona similarmente a tag DTML regular var inserindo valores. Entretanto ela tem alguns atributos da tag visadas na especificação de tipo da SQL, e se relacionando com valores nulos. A tag sqlvar aceita vários argumentos:

name

O argumento name é idêntico ao argumento name da tag var. Este é o nome de uma varável do Zope ou de um argumento do Z SQL Method. O valor da variável ou argumento é inserido dentro do SQL Query Template. Um argumento name é exigido, mas o prefixo "name=" pode ser omitido.

type

O argumento type determina o modo que a tag sqlvar deveria formatar o valor da variável ou argumento a ser inserido no modelo de busca. Valores válidos para o tipo são string, int, float, ou nb. nb é um valor não vazio e determina uma string com pelo menos um caracter nela. Um argumento do tipo sqlvar é exigido.

optional

O argumento optional diz a tag sqlvar que a variável ou argumento pode não estar presente como pode ser um valor nulo. Se a variável ou argumento não existe ou é um valor nulo, a tag sqlvar não tenta renderizá-lo. O argumento optional da tag sqlvar é opcional.

O argumento type é a característica chave da tag sqlvar. Ele é responsável pela especificação correta da variável inserida. Veja o Apêndice A para uma visão mais completa sobre a tag sqlvar.

Você deveria usar sempre a tag sqlvar ao invés da tag var quando inserir variáveis em um código SQL já que ela especifica corretamente as variáveis e mantém seu SQL seguro.

Comparações de Igualdade com a Tag Sqltest

Muitas pesquisas SQL envolvem operações de comparação de igualdade. Estas são pesquisas que pedem por todos os valores da tabela que estão em algum tipo de relação de igualdade com a entrada de dados. Por exemplo, você pode querer buscar na tabela employees todos os empregados com um salário maior que um certo valor.

Para ver como isto é feito, crie um novo Z SQL Method chamado employees_paid_more_than. Dê a ele um argumento, salary, e o seguinte modelo SQL:

  select * from employees
where <dtml-sqltest salary op=gt type=float>

Agora clique em Add and Test. O atributo da tag op é setado para gt, que fica como greater than. Este Z SQL Method retornará somente registros de empregados que tem um salário maior que o aquele que você colocou em seu formulário de entrada de dados. O sqltest constrói a sintaxe necessária da SQL para comparar seguramente a entrada com a coluna da tabela. Digite "10000" no campo salary e clique o botão Test. Como você pode ver a tag sqltest renderiza este código SQL:

  select * from employees
where salary > 10000

A tag sqltest renderiza esta comparação do SQL levando em consideração o tipo da variável e as particularidades do banco de dados. A tag sqltest aceita os seguintes parâmetros da tag:

name

O nome da variável a ser inserida.

type

O tipo do dado do valor a ser inserido. Este atributo é exigido e pode ser string, int, float, ou nb. O tipo de dado nb é um valor não vazio e indica uma string que deve ter um tamanho que é maior que 0. Quando usamos o tipo nb, a tag sqltest não vai renderizar se a variável é uma string vazia.

column

O nome da coluna da SQL, se for diferente do atributo name.

multiple

Um flag indicando se valores múltiplos poedm ser fornecidos. Isto deixa você testar se a coluna é um conjunto de variáveis. Por exemplo quando o name é uma lista de strings "Bob" , "Billy" , <dtml-sqltest name type="string" multiple> renderiza para esta SQL: name in ("Bob", "Billy").

optional

Um flag indicando se o teste é opcional. Se o teste for opcional e nenhum valor é oferecido para uma variável então nenhum texto é inserido. Se o valor é uma string vazia, então nenhum texto será inserido somente se o tipo for nb.

op

Um parâmetro usado para escolher o operador de comparação que é renderizado. As comparações são: eq (igual a), gt (maior que), lt (menor que), ge (maior que ou igual a), le (menor que ou igual a), e ne (diferente de).

Veja o Apêndice A para maiores informações sobre a tag sqltest. Se seu banco de dados suporta operadores de comparação adicionais tais como like você pode usá-lo com a sqlvar. Por exemplo se name é a string "Mc%", o código SQL:

  <dtml-sqltest name type="string" op="like">

renderizado para:

  name like 'Mc%'

A tag sqltest ajuda você construir buscas SQL corretas. Em geral suas buscas serão mais flexíveis e funcionarão melhor com diferentes tipos de entrada e diferentes bancos de dados se você usar sqltest particularmente controlando comparações de código.

Criando Pesquisas Complexas com a Tag Sqlgroup

A tag sqlgroup deixa você criar buscas com SQL que suportam uma quantia variável de argumentos. Baseados em argumentos específicos, buscas com SQL podem ser mais específicas oferecendo mais argumentos, ou menos específicas oferecendo menos ou nenhum arumento.

Aqui está um exemplo de uma busca com SQL inadequada:

  select * from employees

Aqui está um exemplo de uma busca com SQL adequada para salário:

  select * from employees
where(
salary > 100000.00
)

Aqui está um exemplo de uma busca com SQL adequada para salário e primeiro nome:

  select * from employees
where(
salary > 100000.00
and
first in ('Jane', 'Cheetah', 'Guido')
)

Aqui está um exemplo de uma busca com SQL adequada para um primeiro e último nome:

  select * from employees
where(
first = 'Old'
and
last = 'McDonald'
)

Todos estas três buscas podem ser efetuadas com um Z SQL Method que cria mais buscas específicas com SQL como mais argumentos são especificados. O seguinte modelo de SQL pode construir as três buscas acima:

  select * from employees
<dtml-sqlgroup where>
<dtml-sqltest salary op=gt type=float optional>
<dtml-and>
<dtml-sqltest first op=eq type=nb multiple optional>
<dtml-and>
<dtml-sqltest last op=eq type=nb multiple optional>
</dtml-sqlgroup>

A tag sqlgroup renderiza a string where se os conteúdos da tag body contém qualquer texto e constrói as espressões qualificadas dentro da query. Esta tag sqlgroup não renderizará a clausula where se os argumentos não estiverem presentes.

A tag sqlgroup consiste de três blocos separados por tags and. Estas tags inserem a string amd se o final do bloco renderiza um valor. Deste modo o número correto de ands é incluído na busca. Quanto mais argumentos forem epecificados, mais expressões de qualificação serão adicionadas na busca. Neste exemplo, expressões de qualificação restringem a pesquisa com tags and, mas tags or podem também ser usadas para expandir a pesquisa.

Este exemplo mostra também atributos múltiplos nas tags sqltest. Se o primeiro ou segundo valores for uma lista, então a SQL da direita é renderizada para especificar um grupo de valores ao invés de um valor único.

Você também pode colocar tags sqlgroup uma dentro da outra. Por exemplo:

  select * from employees
<dtml-sqlgroup where>
<dtml-sqlgroup>
<dtml-sqltest first op=like type=nb>
<dtml-and>
<dtml-sqltest last op=like type=nb>
</dtml-sqlgroup>
<dtml-or>
<dtml-sqltest salary op=gt type=float>
</dtml-sqlgroup>

Exemplos de argumentos, este modelo renderiza SQL assim:

  select * from employees
where
( (first like 'A%'
and
last like 'Smith'
)
or
salary > 20000.0
)

Você pode construir expressões SQL muito complexas com a tag sqlgroup. Para um simples código SQL você não precisa usar a tag sqlgroup. Entretnto, se você se vê criando vários Z SQl Methods diferentes mas relacionados você deveria ver se você não pode fazer a mesma coisa com um método que usa a tag sqlgroup.

Técnicas Avançadas

Anteriormente você viu como se conectar a um banco de dados relacional, enviando-o buscas e comandos, e criando uma interface de usuário. Estes são os fundamentos básicos para a conexão com um banco de dados no Zope.

Nas seções seguintes você verá mais de perto como integrar com o Zope suas buscas relacionais e como aumentar a performance. Vamos começar olhando como passar argumentos para os Z SQL Methods especificando-os e por aquisição. Então você verá como você pode chamar Z SQL Methods diretamente das URLs usando a passagem para objetos resultantes. Depois você verá como deixar os objetos resultantes mais poderosos ligando-os com as classes. Enfim, veremos sobre cacheamente para melhorar a performance e como o Zope controla as transações com bancos de dados.

Chamando Métodos Z SQL com Argumentos Explícitos

Se você chama um Z SQL Method sem argumento do DTML, os argumentos são automaticamente coletados do ambiente. Esta é a técnica que usamos anteriormente neste capítulo. Ela funciona bem quando você quer pesquisar um banco de dados de um formulário de busca, mas algumas vezes você quer manualmente ou programaticamente pesquisar um banco de dados. Z SQL Methods podem ser chamados com argumentos explícitos do DTML ou Python. Por exemplo, para buscar o Z SQL Method employee_by_id manualmente, o seguinte DTML pode ser usado:

  <dtml-var standard_html_header>
<dtml-in expr="employee_by_id(emp_id=42)">
<h1><dtml-var last>, <dtml-var first></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var
first> makes <dtml-var salary fmt=dollars-and-cents> per year.</p>
</dtml-in>

<dtml-var standard_html_footer>

Lembre-se, o método employee_by_id retorna somente um registro, assim o corpo da tag in neste método executará somente uma vez. No exemplo você chama o Z SQL Method como qualquer outro método e passa para ele um argumento keyword (palavra chave) para emp_id. O mesmo pode ser feito facilmente para Python:

  ## Script (Python) "join_name"
##parameters=id
##
for result in context.employee_by_id(emp_id=id):
return result.last + ', ' + result.first

Este script aceita um argumento de identificação e passa-o para employee_by_id como o emp_id argument. Ele então interage com o resultado único e junta o último nome e o primeiro nome com uma vírgula.

Você pode oferecer mais controle sobre seus dados relacionais chamando os Z SQL Methods com argumentos específicos. Também merece ser frisado que Z SQL Methods podem ser chamados do DTML e Python com argumentos específicos como você chama outros métodos do Zope.

Adquirindo Argumentos Através de Outros Objetos

Z SQL pode adquirir informação sobre outros objetos e ser usado para modificar a busca com SQL. Considere a Figura 10.7, que mostra uma coleção de Pastas no web site de uma organização.

10-7.png

Figura 10.7 - Estrutura de Pastas do web site de uma organização.

Suponha que cada pasta dos departamentos tem uma propriedade string department_id que identifica o id do livro de contabilidade para aquele departamento. Esta propriedade poderia ser usada por um Z SQL Method compartilhado a infromações sobre a busca apenas para aquele departamento. Para ilustrar, crie vários folders um dentro do outro com diferentes propriedades string department_id e então crie um SQL Method com o id requisition_something no folder raiz que tem três argumentos, description, quantity, e unit_cost e o seguinte modelo de busca:

  INSERT INTO requisitions
(
department_id, description, quantity, unit_cost
)
VALUES
(
<dtml-sqlvar department_id type=string>,
<dtml-sqlvar description type=string>,
<dtml-sqlvar quantity type=int>,
<dtml-sqlvar unit_cost type=float>
)

Agora crie uma Z Search Interface com um Search Id "requisitionSomethingForm" e o Report id "requisitionSomething". Selecione o Z SQL Method requisition_something como o Searchable Object e clique Add.

Edite o requisitionSomethingForm e remova a primeira caixa de entrada para o campo department_id. Nós não queremos que o valor de department_id venha do formulário, queremos que venha de uma propriedade que é adquirida.

Agora, você deveria ser capaz de ir a URL:

  http://example.org/Departments/Support/requisitionSomethingForm

e requisitar algumas mochilas do departamento Support. Você também poderia ir para:

  http://example.org/Departments/Sales/requisitionSomethingForm

E requisitar algumas tacky rubber key−chains com seu logo nelas para o departamento Sales. Usando o sistema de segurança do Zope como descrito no Capítulo 7, "Usuários e Segurança", você pode agora restringir acesso a estes formulários assim o pessoal dos departamentos pode requisitar itens apenas para seus departamentos e de nenhum outro.

O interessante sobre este exemplo é que department_id não era um dos argumentos oferecidos para a pesquisa. Ao invés de obter o valor desta variável de um argumento, ele adquire o valor da pasta onde o Z SQL Method é acessado. No caso das URLs acima, o Z SQL Method requisition_something adquire o valor das pastas Sales e Support. Isto permite que você adecue as pesquisas com SQL para diferentes necessidades. Todos os departamentos podem compartilhar uma busca mas ela é padronizada para cada departamento.

Usando aquisição e argumento específico você pode adequar suas pesquisas SQL a suas aplicações web.

Cruzando os Resultados dos Objetos

Anteriormente voccê forneceu argumentos para os Z SQL Methods dos formulários da web, argumentos específicos, e aquisição. Você também pode oferecer argumentos para Z SQL Methods chamando-os da web com URLs especiais. Isto é chamado traversing (cruzamento) para objetos resultantes. Usando esta técnica você pode ir diretamente aos objetos resultantes usando URLs.

Para cruzar objetos resultantes com URLs, você deve ser capaz de assegurar que o SQL Method retornará somente um objeto resultante dando um argumento. Por exemplo, crie um novo Z SQL Method chamado employee_by_id que aceita um argumento, emp_id, e tem o seguinte Modelo SQL:

  select * from employees where
<dtml-sqltest emp_id op=eq type=int>

Este método seleciona um empregado fora da tabela employees baseado no seu id de empregado. Já que cada empregado tem um único id, somente um registro será retornado. Bancos de dados relacionais podem oferecer estes tipos de garantias de exclusividade.

Zope oferece uma sintaxe de URL especial para acessar ZSQL Methods que sempre retorna um resultado único. A URL consiste da URL do ZSQL Method seguido pelo nome do argumento seguido pelo valor do argumento. Por exemplo, http://localhost:8080/employee_by_id/emp_id/42. Observe, esta URL retornará um único objeto como resultado onde se você pesquisou o ZSQL Method do DTML e passou para ele um argumento único ele poderia retornar uma lista de resultados que happend para somente ter um item nele.

Infelizmente o objeto resultante que você obteve com esta URL não é muito interessante para estudar. Não há como mostrá-la em HTML. Você ainda precisa mostrar o objeto resultante. Para fazer isto, você pode chamar um DTML Method no objeto resultante. Isto pode ser feito usando as regras normais de aquisição da URL descritas no Capítulo 10, "Script Avançado em Zope". Por exemplo, considere a seguinte URL:

  http://localhost:8080/employee_by_id/emp_id/42/viewEmployee

Aqui vemos o Z SQl Method employee_by_id passar o argumento emp_id por URL. O método viewEmployee é então chamado no objeto resultante. Vamos criar um DTML Method viewEmployee e testá-lo. Crie um novo DTML Method chamado viewEmployee e dê a ele o seguinte conteúdo:

  <dtml-var standard_html_header>

<h1><dtml-var last>, <dtml-var first></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var
first> makes <dtml-var salary fmt=dollars-;and-cents> per year.</p>

<dtml-var standard_html_footer>

Agora quando você for para a URL http://localhost:8080/employee_by_id/emp_id/42/viewEmployee o DTML Method viewEmployee é ligado ao objeto resultante que é retornado pelo employee_by_id. O método viewEmployee pode ser usado como um modelo genérico usado por diferentes Z SQL Methods que retornam registros de empregados.

Já que o método employee_by_id aceita somente um argumento, ele não precisa especificar emp_id na URL para qualificar o argumento numérico. Se seu Z SQL Method tem um argumento, então você pode configurar o Z SQL Method para aceitar somente um argumento extra do elemento para o caminho ao invés de alguns argumentos. Este exemplo pode ser mais simplificado selecionando o Z SQL Method employee_by_id e clicando na aba Advanced. Aqui, você pode ver uma check box chamada Allow "Simple" Direct Traversal. Selecione esta caixa e clique em Change. Agora, você pode navegar no registro dos empregados com uma URL mais simples http://localhost:8080/employee_by_id/42/viewEmployee. Observe como nenhum emp_id qualificatico é delcarado na URL.

Cruzamentos oferecem um jeito fácil de oferecer argumentos e ligar métodos a Z SQL Methods e seus resultados. Depois vamos mostrar a você como ligar o conjunto de classes a objetos resultantes e torná-los mais poderosos.

Ligando Classes com os Objetos Resultantes

Um objeto resultante tem um atributo para cada coluna nas linhas resultantes. Entretanto, objetos resultantes não tem nenhum método, apenas atributos.

Existem duas maneiras de ligar um método a um objeto resultante. Como você viu na seção anterior, você pode ligar DTML e outros métodos a objetos resultantes de Z SQL Method usando cruzamento para os objetos resultantes unidos com a URL normal baseada no mecanismo de ligamento por aquisição descrito no Capítulo 10, "Scripts Avançados em Zope". Você pode também ligar métodos a objetos resultantes definindo uma classe Python que se misturou com a classe do objeto resultante normal e simples. Estas classes são definidas no mesmo local dos External Methods no sistema de arquivos, no Extensions. As classes do Python são coleções de métodos e atributos. Associando uma classe com um objeto resultante, você pode fazer com que o objeto resultante tenha uma rica API e interfaces de usuário.

Classes usadas para ligar métodos e outros atributos da classe a classes resultantes são chamadas de Pluggable Brains, ou apenas Brains. Considere o exemplo da classe em Python:

  class Employee:
def fullName(self):
""" The full name in the form 'John Doe' """
return self.first + ' ' + self.last

Quando objetos resultantes com esta classe Brains são criadas como resultado de uma busca em um Z SQL Method, os objetos resultantes terão Employee como uma classe base. Isto significa que os objetos registro terão todos os métodos definidos na classe Employee, dando-as comportamento, bem como dados.

Para usar esta classe, crie a classe acima no arquivo Employee.py no diretório Extensions. Vá para a aba Advanced do Z SQl Method employee_by_id e digite Employee no campo Class Name, e Employee no campo Class File e clique Save Changes. Agora você pode editar o DTML Method employeeView para conter:

  <dtml-var standard_html_header>

<h1><dtml-var fullName></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var
first> makes <dtml-var salary fmt=dollars-and-cents> per year.</p>

<dtml-var standard_html_footer>

Agora quando você fpr a URL http://localhost:8080/employee_by_id/42/viewEmployee o método fullName é chamado pelo DTML Method viewEmployee. O método fullName é definido em uma classe Employee do módulo Employee e é ligado ao objeto resultante retornado pelo employee_by_id.

Brains oferece uma facilidade muito poderosa que permite que você trate seus dados relacionais de um modo que centralize o objeto. Por exemplo, você não apenas pode acessar o método fullName usando cruzamento direto, mas você pode usá-lo em qualquer lugar que você estiver controlando ojetos resultantes. Por exemplo:

  <dtml-in employee_by_id>
<dtml-var fullName>
</dtml-in>

Para todos os objetivos práticos seu Z SQL Method retorna uma sequência de objetos espertos, não apenas dados.

Este exemplo somente mostra um pouco do que pode ser feito com as classes Brains. Programaçao em Python está além do escopo deste livro assim mostraremos poucas coisas aqui. Entretanto, você poderia criar classes brains que acessam recusrsos da rede, chamam outros Z SQL Methods, executam todos os tipos de lógica de aplicação.

Aqui está um exemplo mais poderoso de brains. Suponha que você tem uma tabela managers para ir com a tabela employees que você já usou antes. Suponha também que você tem um Z SQL Method manager_by_id que retorna um id do administrador dando um argumento emp_id:

  select manager_id from managers where
<dtml-sqltest emp_id type=int op=eq>

Você poderia usar este Z SQL Method em sua classe brains assim:

  class Employee:

def manager(self):
"""
Returns this employee's manager or None if the
employee does not have a manager.
"""
# Calls the manager_by_id Z SQL Method.
records=self.manager_by_id(emp_id=self.emp_id)
if records:
manager_id=records[0].manager_id
# Return an employee object by calling the
# employee_by_id Z SQL Method with the manager's emp_id
return self.employee_by_id(emp_id=manager_id)[0]

Esta classe Employee mostra como métodos podem usar outros objetos do Zope para tecer juntos dados relacionais para fazer com que pareçam com uma coleção de objetos. O método manager chama dois Z SQL Methods, um para calcular o emp_id do administrador de empregados, e outro para retornar um novo objeto resultante representanteo o administrador. Você pode agora tratar objetos empregados como se eles tivesse simples referências a seus objetos administrador. Por exemplo você poderia adicionar algo como este DTML Method viewEmployee:

  <dtml-if manager>
<dtml-with manager>
<p> My manager is <dtml-var first> <dtml-var last>.</p>
</dtml-with>
</dtml-if>

Como você pode ver brains podem ser ambos complexos e poderosos. Quando estiver projetando aplicações para banco de dados relacionais você deveria tentar manter as coisas simples e adicionar a complexidade aos poucos. É importante ter certeza de que suas classes brains não adicionam muitas sobrecargas desnecessárias.

Cacheando Resultados

Você pode qumentar a performance de suas buscas com SQL usando o cacheamento. Cacheamento armazena resultados dos Z SQL Method assim se você chama algum método com os mesmo argumentos frequentemente, você não precisará se conectar ao banco de dados toda vez. Dependendo de sua aplicação, pode aumentar drasticamente a sua performance.

Para controlar o cacheamento, vá até a aba Advanced de um SQL Method. Você tem três diferentes controles de cache como mostra a Figura 10.8.

10-8.png

Figura 10.8 - Cacheando controle para Z SQL Methods

O campo Maximum number of rows received controla quantos dados cachear para cada busca. O campo Maximum number of results to cache controla quantas buscas cachear. O Maximum time (in seconds) to cache results controla quanto tempo buscas cacheadas são salvas por segundo. Em geral, quanto mais você seta estes valores mais aumenta sua performance, mas mais memória o Zope irá consumir. Como qualquer direcionamento de performance, você deveria tentar achar a melhor configuração para sua aplicação.

Em geral você vai querer setar os resultados máximos para a cache como grandes o suficiente e o tempo máximo para a cache como tempo suficiente para sua aplicação. Para sites com poucos hits você poderia cachear resultados com tempos distantes, e para sites com muitos hits você deveria cachear resultados em um curto período de tempo. Para máquinas com bastante memória você deveria aumentar o número de resultados cacheados. Para desativar o cacheamento configure o tempo da cache para zero segundos. Para a maioria das buscas, o valor default adequado é de 1000 para o maximum number of rows retrieved. Para buscas extremamente grandes você pode ter que aumentar este número para devolver todos os seus resultados.

Transações

Uma transação é um grupo de operações que podem ser desfeitas todas de uma vez. Como você viu no Capítulo 1, "Introduzindo o Zope", todas as mudanças feitas no Zope são feitas dentro de transações. Transações garantem a integridade dos dados. Quando estamos usando um sistema que não é transacional e uma de suas ações web mudam dez objetos, e então falha a mudança de número onze, seus dados estão agora inconsistentes. As transações permitem que você reverta todas as mudanças que você fez durante um request se um erro ocorrer.

Imagine o caso onde você tem uma página web que fatura as mercadorias de um cliente. Esta página primeiro subtrai as mercadorias do inventário, e então subtrai a quantia da conta do cliente. Se a segunda operação falha por alguma razão você quer ter certeza que a mudança no inventário não foi efetivada.

A maioria dos bancos de dados relacionais comerciais e de código aberto suportam transações. Se seu banco de dados relacional suporta transações, o Zope certificar-se-a que elas estão bem amarradas as transações do Zope. Isto garante a integridade dos dados entre seu banco de dados relacional e o Zope. Se tanto o Zope quanto seu banco de dados relacional abortar a transação, a transação inteira é abortada.

Resumo

O Zope permite que você construa aplicações web com banco de dados relcionais. Diferente de muitos servidores de aplicações para web, o Zope tem seu próprio banco de dados objeto e não exige o uso de bancos de dados relacionais para armazenar informações.

O Zope deixa você usar dados relacionais apenas como você usa outros objetos do Zope. você pode conectar seus dados relacionais a lógicas de aplicação com scripts e brains, você pode buscar seus dados relacionais com Z SQL Methods e ferramentas de apresentação como DTLM, e você pode até mesmo usar características avançadas do Zope como cruzamento de URL, aquisição, cancelamento e segurança enquanto trabalha com dados relacionais.

por Diego Pereira do Nascimento Última modificação 09/10/2008 11:46 Creative Commons
Navegação
Enquete
Como você efetiva sua participação comunitária?








Mais »