<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt_BR"><title>Artigos</title><link href="http://artigos.waltercruz.com" rel="alternate"></link><id>http://artigos.waltercruz.com</id><updated>2008-06-29T16:42:23Z</updated><entry><title>Pylons 0.9.6 Cheat Sheet</title><link href="http://artigos.waltercruz.com/pylons_cheatsheet" rel="alternate"></link><updated>2008-06-29T16:42:23Z</updated><author><name>Walter Cruz</name><uri>http://waltercruz.com</uri></author><id>tag:artigos.waltercruz.com,2008-06-29:/pylons_cheatsheet</id><summary type="html">&lt;div class="document" id="pylons-0-9-6-cheat-sheet"&gt;
&lt;h1 class="title"&gt;Pylons 0.9.6 Cheat Sheet&lt;/h1&gt;
&lt;table class="docinfo" frame="void" rules="none"&gt;
&lt;col class="docinfo-name" /&gt;
&lt;col class="docinfo-content" /&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="docinfo-name"&gt;Author:&lt;/th&gt;
&lt;td&gt;Copyright (C) 2007 Dipl.-Inform. Christoph Haas &amp;lt;&lt;a class="reference" href="mailto:email&amp;#64;christoph-haas.de"&gt;email&amp;#64;christoph-haas.de&lt;/a&gt;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="field"&gt;&lt;th class="docinfo-name"&gt;IRC:&lt;/th&gt;&lt;td class="field-body"&gt;Meet me at #pylons on irc.freenode.net as Signum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="field"&gt;&lt;th class="docinfo-name"&gt;License:&lt;/th&gt;&lt;td class="field-body"&gt;&lt;p class="first"&gt;This document is published under the terms of the MIT license:&lt;/p&gt;
&lt;p&gt;Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:&lt;/p&gt;
&lt;p&gt;The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.&lt;/p&gt;
&lt;p class="last"&gt;The software is provided &amp;quot;as is&amp;quot;, without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall the
authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising
from, out of or in connection with the software or the use or other
dealings in the software.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- -*- coding: utf-8 -*-

This file is written in REST (restructured text) format.
The format is documented at http://docutils.sourceforge.net/docs/
Install the "python-docutils" Debian package to get tools like
rst2html or rst2latex that convert this file into other formats. --&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;O fonte desse documento está disponível em um repositório Mercurial
em &lt;a class="reference" href="http://workaround.org/cgi-bin/hg-pylons-cheatsheet"&gt;http://workaround.org/cgi-bin/hg-pylons-cheatsheet&lt;/a&gt; -
por favor, envie patches para &lt;a class="reference" href="mailto:email&amp;#64;christoph-haas.de"&gt;email&amp;#64;christoph-haas.de&lt;/a&gt; mesmo que você esteja
lendo esse texto em wiki.pylonshq.com. Obrigado.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="contents topic"&gt;
&lt;p class="topic-title first"&gt;&lt;a id="contents" name="contents"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="#pylons" id="id1" name="id1"&gt;Pylons&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="#links" id="id2" name="id2"&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#instala-o" id="id3" name="id3"&gt;Instalação&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#projeto-paste" id="id4" name="id4"&gt;Projeto (Paste)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#development-ini" id="id5" name="id5"&gt;development.ini&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#estrutura-de-diret-rios" id="id6" name="id6"&gt;Estrutura de Diretórios&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#controladores" id="id7" name="id7"&gt;Controladores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#objetos-globais" id="id8" name="id8"&gt;Objetos globais&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#routes" id="id9" name="id9"&gt;Routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#mako-templates" id="id10" name="id10"&gt;Mako (Templates)&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="#template-base-de-exemplo-a-ser-herdado" id="id11" name="id11"&gt;Template base de exemplo (a ser herdado)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#herdando-de-um-template-base" id="id12" name="id12"&gt;Herdando de um template base&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#acesso-a-banco-de-dados" id="id13" name="id13"&gt;Acesso a banco de dados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#sess-es-baseadas-em-cookies" id="id14" name="id14"&gt;Sessões baseadas em cookies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#formencode" id="id15" name="id15"&gt;Formencode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#bibliotecas-javascript" id="id16" name="id16"&gt;Bibliotecas Javascript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#webhelpers" id="id17" name="id17"&gt;Webhelpers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#internacionaliza-o-i18n" id="id18" name="id18"&gt;Internacionalização (i18n)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#testes-unit-rios-nose" id="id19" name="id19"&gt;Testes Unitários (Nose)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#comunidade" id="id20" name="id20"&gt;Comunidade&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#add-ons-relacionados" id="id21" name="id21"&gt;Add-ons Relacionados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id1" id="pylons" name="pylons"&gt;Pylons&lt;/a&gt;&lt;/h1&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2" id="links" name="links"&gt;Links&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://pylonshq.com/"&gt;Home&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://wiki.pylonshq.com/display/pylonsdocs/Getting+Started"&gt;Iniciando&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://pylonshq.com/docs/module-index.html"&gt;Referência dos módulos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://wiki.pylonshq.com/display/pylonsfaq/Home"&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://wiki.pylonshq.com/dashboard.action"&gt;Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3" id="instala-o" name="instala-o"&gt;Instalação&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Debian/Ubuntu&lt;ul&gt;
&lt;li&gt;Instalação: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;aptitude&lt;/span&gt; &lt;span class="pre"&gt;install&lt;/span&gt; &lt;span class="pre"&gt;python-pylons&lt;/span&gt;&lt;/tt&gt; (disponível no lenny/testing ou
sid/unstable mas não no Etch!)&lt;/li&gt;
&lt;li&gt;Atualização: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;aptitude&lt;/span&gt; &lt;span class="pre"&gt;update&lt;/span&gt; &lt;span class="pre"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="pre"&gt;aptitude&lt;/span&gt; &lt;span class="pre"&gt;install&lt;/span&gt; &lt;span class="pre"&gt;python-pylons&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Easy-Install:&lt;ul&gt;
&lt;li&gt;Instalação: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;easy_install&lt;/span&gt; &lt;span class="pre"&gt;Pylons&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Atualização: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;easy_install&lt;/span&gt; &lt;span class="pre"&gt;-U&lt;/span&gt; &lt;span class="pre"&gt;Pylons&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://python.org/pypi/virtualenv/"&gt;virtualenv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4" id="projeto-paste" name="projeto-paste"&gt;Projeto (Paste)&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Criar um novo projeto&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;create&lt;/span&gt; &lt;span class="pre"&gt;-t&lt;/span&gt; &lt;span class="pre"&gt;pylons&lt;/span&gt; &lt;span class="pre"&gt;myapplicationsname&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Remova a página de boas vindas &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;public/index.html&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Configure o roteamento em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config/routing.py&lt;/span&gt;&lt;/tt&gt; (por exemplo, colocar o '' para iniciar um controlador)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Atualizar o projeto para a nova versão do Pylons: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;create&lt;/span&gt; &lt;span class="pre"&gt;-t&lt;/span&gt; &lt;span class="pre"&gt;pylons&lt;/span&gt; &lt;span class="pre"&gt;myapplicationsname&lt;/span&gt;&lt;/tt&gt;
(De um diretório acima de onde o seu development.ini está localizado)&lt;/li&gt;
&lt;li&gt;Servir a aplicação via HTTP: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;serve&lt;/span&gt; &lt;span class="pre"&gt;--reload&lt;/span&gt; &lt;span class="pre"&gt;development.ini&lt;/span&gt;&lt;/tt&gt;
(a aplicação executa em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://localhost:5000&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Shell interativo: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;shell&lt;/span&gt;&lt;/tt&gt; (instale o &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ipython&lt;/span&gt;&lt;/tt&gt; para facilidades adicionais)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://sluggo.scrapping.cc/python/pylons/pylons-execution.html"&gt;Detalhes de como funciona a execução do Pylons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5" id="development-ini" name="development-ini"&gt;development.ini&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[server:main]&lt;/span&gt;&lt;/tt&gt; (Paste)&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;use&lt;/span&gt;&lt;/tt&gt;: aponta para o egg do servidor web do Paste&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/tt&gt;: O IP que irá esperar as requisições&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;port&lt;/span&gt;&lt;/tt&gt;: a porta TCP no qual o servidor web espera as requisições&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[app:main]&lt;/span&gt;&lt;/tt&gt; (Pylons)&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;use&lt;/span&gt;&lt;/tt&gt;: aponta para a sua aplicação&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;full_stack&lt;/span&gt;&lt;/tt&gt;: XXX&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cache_dir&lt;/span&gt;&lt;/tt&gt;: diretório onde os templates HTML em cache e as sessões são salvas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;%(here)s&lt;/span&gt;&lt;/tt&gt; refere-se a raiz do projeto (onde está o development.ini))&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Acessando configurações da seção &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[app:main]&lt;/span&gt;&lt;/tt&gt; :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pylons&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
&lt;span class="n"&gt;my_setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6" id="estrutura-de-diret-rios" name="estrutura-de-diret-rios"&gt;Estrutura de Diretórios&lt;/a&gt;&lt;/h2&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="43%" /&gt;
&lt;col width="57%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;data/sessions&lt;/td&gt;
&lt;td&gt;Sessões são salvas em arquivos nesse
diretório.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;data/templates&lt;/td&gt;
&lt;td&gt;Arquivos HTML em cache que são
renderizados a partir de seus templates
são armazenados aqui.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;development.ini&lt;/td&gt;
&lt;td&gt;A configuração de inicialização
do Paste.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/config/&lt;/td&gt;
&lt;td&gt;Arquivos de configuração globais
do seu projeto. Usados para
definir rotas para o processamento
de URLS, middleware (como a
adição de autentição) ou o
sistema de template de sua preferência&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/controllers/&lt;/td&gt;
&lt;td&gt;A localização das classes que
contém a lógica da sua aplicação.
Esse código controla sua
aplicação, renderiza templates
e consulta o banco de dados.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/docs/&lt;/td&gt;
&lt;td&gt;Coloque qualquer documentação da
aplicação aqui. De preferência no formato
rest (restructured text).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/i18n/&lt;/td&gt;
&lt;td&gt;Arquivos que lidam com as mensagens
localizadas do seu projeto.
(i18n = internacionalização)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/lib/&lt;/td&gt;
&lt;td&gt;Contém arquivos que configuram
certas variáveis globais e
objetos que você pode usar em seus
controladores. Por exemplo,
tudo em lib/base.py está disponível
em todos os seus controladores.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/model/&lt;/td&gt;
&lt;td&gt;Aqui vai o model do seu banco de dados.
Eles definem o esquema do banco de dados
e configuram o mapeamento objeto-relacional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/public/&lt;/td&gt;
&lt;td&gt;Arquivos estáticos como imagens, CSS
ou javascripts devem ficar aqui&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/templates/&lt;/td&gt;
&lt;td&gt;Seus templates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;myapplication/tests/&lt;/td&gt;
&lt;td&gt;Cada controlador que você cria
ganha uma contraparte para implementar
testes automatizados aqui.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;README.txt&lt;/td&gt;
&lt;td&gt;Algumas instruções básicas que você
pode dar ao administrador
que irá instalar sua aplicação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ez_setup,
myapplication.egg-info,
setup.cfg,
setup.py&lt;/td&gt;
&lt;td&gt;Arquivos administrativos que são usados
para criar um egg do seu projeto
para que possa ser feito o deploy
no servidor web.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;test.ini&lt;/td&gt;
&lt;td&gt;Semelhante ao development.ini.
Esse arquivo é usando quando você quer
rodar testes automatizados no seu projeto&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id7" id="controladores" name="controladores"&gt;Controladores&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Criar um novo controlador: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;controller&lt;/span&gt; &lt;span class="pre"&gt;name-of-new-controller&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;O controlador &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mycontroller&lt;/span&gt;&lt;/tt&gt; está localizado em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;controllers/mycontroller.py&lt;/span&gt;&lt;/tt&gt; como a classe &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;MycontrollerController&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;O método &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;index&lt;/span&gt;&lt;/tt&gt;  é chamado quando nenhuma ação é especificada&lt;/li&gt;
&lt;li&gt;Todos os símbolos de &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lib/base.py&lt;/span&gt;&lt;/tt&gt; são importados&lt;/li&gt;
&lt;li&gt;Os parâmetros definidos no Routes podem ser aceitos como argumentos:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Your ID is &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Outros parâmetros estão disponíveis através de  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;request.params['my_paramter']&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Valores de retorno&lt;ul&gt;
&lt;li&gt;Uma string (unicode)&lt;/li&gt;
&lt;li&gt;Renderização de um template Mako: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;render('/mytemplate')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Envio de um código de erro HTTP: abort(404)&lt;/li&gt;
&lt;li&gt;Um iterador (&lt;a class="reference" href="http://docs.pythonweb.org/display/pylonsfaq/Streaming+Content+to+the+Browser"&gt;Exemplo de um StreamingController&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Redirecionando para outra URL: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;redirect_to(controller='start',&lt;/span&gt; &lt;span class="pre"&gt;action='about')&lt;/span&gt;&lt;/tt&gt;
ou &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;redirect_to('/start/about')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Modificando o objeto de respota (a ser feito antes da declaração &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;return&lt;/span&gt;&lt;/tt&gt; da action:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/xml; charset=utf-8&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;sitelang&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;uk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;201&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id8" id="objetos-globais" name="objetos-globais"&gt;Objetos globais&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Os dados da configuração estão disponíveis através do objeto &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;Variáveis da seção &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;app:main&lt;/span&gt;&lt;/tt&gt; do &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;development.ini&lt;/span&gt;&lt;/tt&gt;:&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first last"&gt;dicionário &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['app_conf']&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;Variáveis da seção &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[DEFAULT]&lt;/span&gt;&lt;/tt&gt; do &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;development.ini&lt;/span&gt;&lt;/tt&gt;:&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first last"&gt;dicionário &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['global_conf']&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Caminho absoluto do arquivo ini: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['__file__']&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Nome da aplicação: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['package']&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['pylons.package']&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Caminho para o projeto atual: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['here']&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;O objeto 'h' (webhelpers): &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['pylons.h']&lt;/span&gt;&lt;/tt&gt; (configurado em config/environment.py)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;O objeto 'g' (globals): &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['pylons.g']&lt;/span&gt;&lt;/tt&gt; (configurado em config/environment.py)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;A configuração do Path (onde controladores, templates e arquivos estáticos são&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first last"&gt;localizados): &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config['pylons.paths']&lt;/span&gt;&lt;/tt&gt; (configurado em config/environment.py)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id9" id="routes" name="routes"&gt;Routes&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Links&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="http://routes.groovie.org/"&gt;Home&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://routes.groovie.org/manual.html"&gt;Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Definidos em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;config/routing.py&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;O controlador inicial (para o caminho &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;) pode ser especificado como &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map.connect('',&lt;/span&gt; &lt;span class="pre"&gt;controller='start')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map.connect('newstoday',&lt;/span&gt; &lt;span class="pre"&gt;controller='news')&lt;/span&gt;&lt;/tt&gt; -&amp;gt; chama ''class
NewsController'' no  arquivo &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;controllers/news.py&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Argumentos adicionais são passados para o método do controlador como argumentos nomeados
(e.g. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;def&lt;/span&gt; &lt;span class="pre"&gt;__index__(self,&lt;/span&gt; &lt;span class="pre"&gt;id,&lt;/span&gt; &lt;span class="pre"&gt;name,&lt;/span&gt; &lt;span class="pre"&gt;city):&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id10" id="mako-templates" name="mako-templates"&gt;Mako (Templates)&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Unicode&lt;ul&gt;
&lt;li&gt;Inicie todos os templates com : &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#&lt;/span&gt; &lt;span class="pre"&gt;-*-&lt;/span&gt; &lt;span class="pre"&gt;coding:&lt;/span&gt; &lt;span class="pre"&gt;utf-8&lt;/span&gt; &lt;span class="pre"&gt;-*-&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Comandos (não esqueça o ':' final)&lt;ul&gt;
&lt;li&gt;% for / % endfor&lt;/li&gt;
&lt;li&gt;% if / % elif / % else / % endif&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Impressão de variáveis&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;${&lt;/span&gt; &lt;span class="pre"&gt;c.variablename&lt;/span&gt; &lt;span class="pre"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;The closing bracket must not be used alone on a line&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id11" id="template-base-de-exemplo-a-ser-herdado" name="template-base-de-exemplo-a-ser-herdado"&gt;Template base de exemplo (a ser herdado)&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;# -*- coding: utf-8 -*-
&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;en&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;xml:lang=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;...........&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    ${ h.stylesheet_link_tag( &amp;#39;/style1.css&amp;#39;, &amp;#39;/style2.css&amp;#39;) }
    ${ h.javascript_include_tag( &amp;#39;jquery.js&amp;#39;, &amp;#39;jquery.debug.js&amp;#39;) }
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;shortcut icon&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;image/x-icon&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/favicon.ico&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;My application&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    ${ next.body() }
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id12" id="herdando-de-um-template-base" name="herdando-de-um-template-base"&gt;Herdando de um template base&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;# -*- coding: utf-8 -*-
&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;%inherit file=&amp;quot;master.mako&amp;quot;/&amp;gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id13" id="acesso-a-banco-de-dados" name="acesso-a-banco-de-dados"&gt;Acesso a banco de dados&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Links de documentação&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.sqlalchemy.org/docs/"&gt;SQLAlchemy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://dev.mysql.com/doc/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.sqlite.org/docs.html"&gt;SQLite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;pylons.database&lt;/em&gt; e &lt;em&gt;SAContext&lt;/em&gt; estão obsoletos!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Veja &lt;a class="reference" href="http://wiki.pylonshq.com/display/pylonsdocs/Using+SQLAlchemy+with+Pylons"&gt;Usando SQLAlchemy com Pylons&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;development.ini:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sqlalchemy.url = sqlite:///%(here)s/phonebook.db
sqlalchemy.url = mysql://username:password&amp;#64;host:3306/database
sqlalchemy.url = postgres://username:password&amp;#64;host:5432/database
sqlalchemy.url = oracle://username:password&amp;#64;host:1521/sidname
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Opções&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;O MySQL fecha conexões inativas automaticamente. Você precisará:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sqlalchemy.pool_recycle = 3600
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Imprimir todas as consultas para o console (você pode usar também o módulo 'logging'
como descrito na &lt;a class="reference" href="http://www.sqlalchemy.org/docs/04/dbengine.html#dbengine_logging"&gt;Documentação do SQLAlchemy&lt;/a&gt;):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sqlalchemy.echo = True
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;a class="reference" href="http://www.sqlalchemy.org/docs/04/dbengine.html#dbengine_options"&gt;Lista completa de opções suportadas&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Definindo tabelas e &lt;a class="reference" href="http://www.sqlalchemy.org/docs/04/ormtutorial.html"&gt;mapeamento objeto relacional&lt;/a&gt; in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model/__init__.py&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Mapeamento simples:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;sql&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;orm&lt;/span&gt;

&lt;span class="c"&gt;# Define table&lt;/span&gt;
&lt;span class="n"&gt;my_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;tablename&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;    &lt;span class="c"&gt;# gets a sequence/serial assigned&lt;/span&gt;
    &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;othertable_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;othertable.id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Define object class for ORM-mapping (every object matches one row)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;MyModel (&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;)&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;my_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Teste o acesso aos modelos mapeados confortavelmente usando &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;shell&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Criando consultas e obtendo resultados&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter uma linha com certo conteúdo em um campo (levanta uma exceção se mais linhas são retornadas):
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).filter_by(name='John').one()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter um iterador de itens combinando com certo critério:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).filter(model.MyModel.name=='John')&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter um iterador de itens com certo conteúdo:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).filter_by(name='John')&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter um iterador de itens selecionados por uma condição SQL personalizada:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).filter_by(&amp;quot;id&amp;lt;:value&lt;/span&gt; &lt;span class="pre"&gt;and&lt;/span&gt; &lt;span class="pre"&gt;name=:name&amp;quot;).params(value=224,&lt;/span&gt; &lt;span class="pre"&gt;name='fred')&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter a linha com a chave primária 42:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).get(42)&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter todas as linhas:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).all()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter a primeira linha:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).first()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter a única linha(levanta uma exceção se mais linhas são retornadas):
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).one()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Obter um número limitado de linhas (como uma lista)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).offset(50).limit(10).all()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel)[10:50].all()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Ordenar linhas&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).order_by(model.MyModel.age).all()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).order_by(model.sql.desc(model.MyModel.age)).all()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).order_by([model.MyModel.age,&lt;/span&gt; &lt;span class="pre"&gt;model.MyModel.city]).all()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Contar linhas em um resultado:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.MyModel).count()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Joins (cuidado com produtos cartesianos):
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;model.Session.query(model.Model1,&lt;/span&gt; &lt;span class="pre"&gt;model.Model2).all()&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter_by&lt;/span&gt;&lt;/tt&gt; for generative queries:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
query = model.Session.query(model.MyModel)
query = query.filter_by(name='John', type=189)
query = query.filter_by(city='Hamburg')
results = query.all()
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Operadores lógicos&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;AND: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;and_(condition1,&lt;/span&gt; &lt;span class="pre"&gt;condition2,&lt;/span&gt; &lt;span class="pre"&gt;...)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;AND: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(condition1&lt;/span&gt; &lt;span class="pre"&gt;&amp;amp;&lt;/span&gt; &lt;span class="pre"&gt;condition2&lt;/span&gt; &lt;span class="pre"&gt;&amp;amp;&lt;/span&gt; &lt;span class="pre"&gt;...)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;OR: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;or_(condition1,&lt;/span&gt; &lt;span class="pre"&gt;condition2,&lt;/span&gt; &lt;span class="pre"&gt;...)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;OR: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(condition1&lt;/span&gt; &lt;span class="pre"&gt;|&lt;/span&gt; &lt;span class="pre"&gt;condition2&lt;/span&gt; &lt;span class="pre"&gt;|&lt;/span&gt; &lt;span class="pre"&gt;...)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;NOT: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;not_(condition)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;NOT: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~(condition)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Operadores de consulta:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;==&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;=&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;gt;=&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;startswith('foo')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;endswith('.com')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;like('%jean')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;between(100,500)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;in('A',&lt;/span&gt; &lt;span class="pre"&gt;'CNAME',&lt;/span&gt; &lt;span class="pre"&gt;'MX')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;+&lt;/span&gt;&lt;/tt&gt; (concatenation of strings)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;op('...')&lt;/span&gt;&lt;/tt&gt; (custom operator)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;==None&lt;/span&gt;&lt;/tt&gt; (NULL comparison)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Funções de consulta:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Sintaxe geral: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;func.FUNCTIONNAME(...)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;e.g. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;func.count()&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;func.now()&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Criando novos objetos:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;new_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;new_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Jane&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;new_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Tokio&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# not needed if set autoflush=True&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# needed because SQLAlchemy 0.4 uses transactions everywhere&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Alterando objetos:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;old_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;old_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Paris&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# not needed if set autoflush=True&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# needed because SQLAlchemy 0.4 uses transactions everywhere&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Removendo objetos (não use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;del(...)&lt;/span&gt;&lt;/tt&gt;):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;old_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# not needed if set autoflush=True&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# needed because SQLAlchemy 0.4 uses transactions everywhere&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Seleções arbitrárias (retorna o que você especifica ao invés de linhas completas):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;some_column&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# or .fetchmany() or .fetchone()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.sqlalchemy.org/docs/types.html"&gt;Tipos&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;String(length=None) [&lt;em&gt;é melhor usar Unicode&lt;/em&gt;]&lt;/li&gt;
&lt;li&gt;Integer&lt;/li&gt;
&lt;li&gt;SmallInteger&lt;/li&gt;
&lt;li&gt;Numeric(precision=10, length=2)&lt;/li&gt;
&lt;li&gt;Float(precision=10)&lt;/li&gt;
&lt;li&gt;DateTime [corresponds to datetime.datetime]&lt;/li&gt;
&lt;li&gt;Date [corresponds to datetime.date]&lt;/li&gt;
&lt;li&gt;Time [corresponds to datetime.time]&lt;/li&gt;
&lt;li&gt;Binary(length=None)&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;li&gt;Unicode(length=None)&lt;/li&gt;
&lt;li&gt;PickleType&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- ::

Removed temporarily because 0.3 is stable but buggy while
0.4 is rumored to be good but not documented.
===========================
Autenticação (Authkit)
===========================

- Change your ``config/middleware.py`` where it says ``if asbool(full_stack)`` to::

    if asbool(full_stack):
        import authkit.authenticate
        app = authkit.authenticate.middleware(app, app_conf=app_conf, global_conf=global_conf)

- development.ini

  - authkit.enable = true
  - authkit.setup.method = forward
  - authkit.forward.internalpath = /start/login
  - authkit.cookie.secret   = qwertzuiop
  - authkit.cookie.name = dnsdhcp_auth
  - authkit.cookie.params = max-age:86400
  - authkit.cookie.signout  = /start/logout
  - authkit.cookie.includeip = True

- O ``authkit.cookie.name`` deve ser diferente de ``beaker.session.key``

- Habilitar logging (em ``config/middleware.py`` logo após o authkit.authenticate.middleware)::

    import logging
    log_StreamHandler = logging.StreamHandler() # points to stderr
    authkit.authenticate.log.addHandler(log_StreamHandler)
    authkit.authenticate.log.setLevel(logging.DEBUG) --&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id14" id="sess-es-baseadas-em-cookies" name="sess-es-baseadas-em-cookies"&gt;Sessões baseadas em cookies&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;a class="reference" href="http://beaker.groovie.org/"&gt;Página do Beaker&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;development.ini&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.key&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;myproject_session&lt;/span&gt;&lt;/tt&gt;
(nome do cookie de sessão sendo enviado ao navegador)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.secret&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;somesecret&lt;/span&gt;&lt;/tt&gt; (random string that the cookie
string sent to the user is signed with)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.cookie_expires&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;True&lt;/span&gt;&lt;/tt&gt;
(whether the cookie is a session cookie that expires when the browser
is closed)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.timeout&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;...&lt;/span&gt;&lt;/tt&gt; (time in seconds until the session
times out)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.data_dir&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;...&lt;/span&gt;&lt;/tt&gt; (path where the 'sessions' directory
is located storing the session data)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.type&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;...&lt;/span&gt;&lt;/tt&gt; (Storage type for session information.)&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dbm&lt;/span&gt;&lt;/tt&gt; stores sessions in files on disk&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;file&lt;/span&gt;&lt;/tt&gt; stores sessions in files on disk&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;memory&lt;/span&gt;&lt;/tt&gt; stores sessions in RAM&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ext:memcached&lt;/span&gt;&lt;/tt&gt; stores sessions on
&lt;a class="reference" href="http://www.danga.com/memcached/"&gt;memcached&lt;/a&gt; servers.
Memcache servers are configured as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;beaker.session.url&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt;
&lt;span class="pre"&gt;server1,&lt;/span&gt; &lt;span class="pre"&gt;server2,&lt;/span&gt; &lt;span class="pre"&gt;..&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;A variavel &lt;em&gt;session&lt;/em&gt; vem de &lt;em&gt;pylons.session&lt;/em&gt; e é importada
em seu &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lib/base.py&lt;/span&gt;&lt;/tt&gt;. Ela se comporta como um dicionário.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Carregando um valor da sessão:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
value = session['whatever']
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Salvando um valor na sessão:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
session['whatever'] = value
session.save()
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Removendo uma chave da sessão:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
del session['whatever']
session.save()
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Limpando a sessão:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;session.clear()
session.save()&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id15" id="formencode" name="formencode"&gt;Formencode&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Documentação&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="http://formencode.org"&gt;Sítio do Formencode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Formulários são validados através de subclasses de
&lt;a class="reference" href="http://formencode.org/module-formencode.schema.html"&gt;formencode.schema&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Validadores customizados são normalmente subclasses de
&lt;a class="reference" href="http://formencode.org/class-formencode.validators.FancyValidator.html"&gt;formencode.FancyValidator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://formencode.org/Validator.html#writing-your-own-validator"&gt;Escrevendo validadores customizados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Usando formencode:&lt;ul&gt;
&lt;li&gt;Defina um schema de validação&lt;/li&gt;
&lt;li&gt;Decore o método/ação do seu controlador (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;formencode.validate(MySchema)&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Se o formulário que o usuário enviou não validar então o formencode irá
reexecutare a ação atual (ou executar a ação que você especificou como
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;form&lt;/span&gt;&lt;/tt&gt;) como em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;formencode.validate(MySchema,&lt;/span&gt; &lt;span class="pre"&gt;form='anotheraction')&lt;/span&gt;&lt;/tt&gt;
e mostrar as mensagens de erro bem acima dos inputs com uma classe CSS
chamada '.error-message'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Exemplo de classe de validação:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# My form schema&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formencode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;allow_extra_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;filter_extra_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formencode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;not_empty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formencode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# MySchema schema without the &amp;#39;days&amp;#39; field&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySchema2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;   &lt;span class="c"&gt;# (removes days field from the superclass)&lt;/span&gt;

&lt;span class="c"&gt;# MySchema schema with additional &amp;#39;comment&amp;#39; field&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySchema3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MySchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Subclass variables:&lt;ul&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;allow_extra_fields&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;False&lt;/span&gt;&lt;/tt&gt; (whether to display an error if fields are
found in the POST request that are not mentioned in this subclass)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter_extra_fields&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;False&lt;/span&gt;&lt;/tt&gt; (whether to remove fields that are not
mentioned in this subclass)
are missing in the POST request but defined in this subclass)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ignore_key_missing&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;False&lt;/span&gt;&lt;/tt&gt; (whether to display an error if fields
are missing in the POST request but defined in this subclass)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if_key_missing&lt;/span&gt;&lt;/tt&gt; (fields that are missing in the POST request will get
this value assigned)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id16" id="bibliotecas-javascript" name="bibliotecas-javascript"&gt;Bibliotecas Javascript&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;jQuery (pequna bibloteca Javascript com uma porção de plugins)&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="http://jquery.com/"&gt;Home&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://jquery.com/plugins/"&gt;Plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prototype (Biblioteca Javascript)&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="http://wiki.script.aculo.us/scriptaculous/show/PrototypeOverview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://blogs.ebusiness-apps.com/jordan/pages/Prototype%20Library%20Info.htm"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://particletree.com/features/quick-guide-to-prototype"&gt;Guia Rápido&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.sergiopereira.com/articles/prototype.js.html"&gt;Usando Prototype&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;script.aculo.us (Javascript effects library built on top of Prototype)
- &lt;a class="reference" href="http://script.aculo.us/"&gt;Home&lt;/a&gt;
- &lt;a class="reference" href="http://wiki.script.aculo.us/scriptaculous/show/Demos"&gt;Demos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id17" id="webhelpers" name="webhelpers"&gt;Webhelpers&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;As funções de &lt;em&gt;webhelpers.rails&lt;/em&gt; são importadas automaticamente&lt;/li&gt;
&lt;li&gt;Controllers and templates can access the webhelpers module by the 'h' (helper) name&lt;/li&gt;
&lt;li&gt;Links:&lt;ul&gt;
&lt;li&gt;&lt;a class="reference" href="http://pylonshq.com/WebHelpers/module-index.html"&gt;Referência&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id18" id="internacionaliza-o-i18n" name="internacionaliza-o-i18n"&gt;Internacionalização (i18n)&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Instale o  &lt;em&gt;Babel&lt;/em&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Debian/Ubuntu: aptitude install python-babel&lt;/li&gt;
&lt;li&gt;Outros sistemas operacionais: easy_install Babel&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;a class="reference" href="http://wiki.pylonshq.com/display/pylonsdocs/Internationalization+and+Localization"&gt;Artigo do wiki&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Edite o seu &lt;cite&gt;setup.py&lt;/cite&gt; e habilite a seção &lt;cite&gt;message_extractors&lt;/cite&gt; para interpretar strings gettext nos templates.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Use a função &amp;quot;_&amp;quot; (um alias para a função gettext) sempre que você precisar de strings normais.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Controladores: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;_('Hello&lt;/span&gt; &lt;span class="pre"&gt;World')&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Templates Mako : &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;${&lt;/span&gt; &lt;span class="pre"&gt;_('Hello&lt;/span&gt; &lt;span class="pre"&gt;World')&lt;/span&gt; &lt;span class="pre"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Primeira vez:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Criar um &lt;em&gt;pot&lt;/em&gt; template no diretório &lt;em&gt;i18n&lt;/em&gt;: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;extract_messages&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Criar um arquivo &lt;em&gt;po&lt;/em&gt; para cada idioma (aqui o idioma é 'es'): &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;init_catalog&lt;/span&gt; &lt;span class="pre"&gt;-l&lt;/span&gt; &lt;span class="pre"&gt;es&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Editar o arquivo &lt;em&gt;po&lt;/em&gt; em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;i18n/es/LC_MESSAGES/*.po&lt;/span&gt;&lt;/tt&gt; e adicionar strings traduzidas nos campos &lt;em&gt;msgstr&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Compile the &lt;em&gt;po&lt;/em&gt; files into &lt;em&gt;mo&lt;/em&gt; files: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;compile_catalog&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Update:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Overwrite the english &lt;em&gt;pot&lt;/em&gt; template:: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;extract_messages&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Update the &lt;em&gt;po&lt;/em&gt; files with new strings (does not overwrite the already translated strings): &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;update_catalog&lt;/span&gt; &lt;span class="pre"&gt;-l&lt;/span&gt; &lt;span class="pre"&gt;es&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Compile the &lt;em&gt;po&lt;/em&gt; files into &lt;em&gt;mo&lt;/em&gt; files: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;compile_catalog&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Dica: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paster&lt;/span&gt; &lt;span class="pre"&gt;serve&lt;/span&gt; &lt;span class="pre"&gt;--reload&lt;/span&gt;&lt;/tt&gt; não detecta mudanças na internacionalização. Você irá precisar reiniciar o servidor web.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Para configurar a linguagem do gettext de acordo com a língua do navegador adicione isso ao seu &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lib/base.py&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
def __before__(self):
    user_agent_language = request.languages[0][0:2]
    set_lang(user_agent_language)
&lt;/pre&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;request.languages&lt;/span&gt;&lt;/tt&gt; is an array of preferred languages that the users sets in the browser.
I.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;['de',&lt;/span&gt; &lt;span class="pre"&gt;'en',&lt;/span&gt; &lt;span class="pre"&gt;'en-us']&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id19" id="testes-unit-rios-nose" name="testes-unit-rios-nose"&gt;Testes Unitários (Nose)&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://somethingaboutorange.com/mrl/projects/nose/"&gt;Página do Nose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id20" id="comunidade" name="comunidade"&gt;Comunidade&lt;/a&gt;&lt;/h1&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;#pylons &amp;#64; irc.freenode.net&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a class="toc-backref" href="#id21" id="add-ons-relacionados" name="add-ons-relacionados"&gt;Add-ons Relacionados&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://code.google.com/p/formalchemy/"&gt;FormAlchemy&lt;/a&gt;:
Cria formulários HTML automaticamente a partir de schemas do SQLAlchemy (classes mapeadas)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://paginate.workaround.org/"&gt;Paginator&lt;/a&gt;:
Ajuda a dividir um número grande de resultados em páginas e permite que o usuário navegue
entre as páginas&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://code.google.com/p/dbsprockets/"&gt;DBSprockets&lt;/a&gt;:
Automaticamente cria formulários do  Toscawidget e validadores do Formencode para schemas
(classes mapeadas)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;!-- ::


= Controllers / Actions =

Whether a controller or a static file is served when calling a certain action is defined
by the search path ''Cascade'' in the {{{config/middleware.py}}} file.
''public/index.html'' is always served first unless you delete it.

Actions (methods of the controller) are not publicly visible if their names start
with an underscore (_).

Parameter as defined in config/routing.py that are neither ''action'' nor ''controller''
are passed to the controllers' actions as named parameter. If you are using the default {{{:controller/:action/:id}}} schema and have a URL http://myserver/news/view/10 that will call the controller named NewsController (Pylons looks for a controller called the name in with an uppercase first character plus the word "Controller") with the method/action ''view''. The additional parameter 'id' is passed as an argument to the function:

{{{
class NewsController(BaseController):
    def view(self, id):
        return Response('You wanted to read news article number %s' % id)
}}}

= Templates =

Templates are text files that reside in the templates/ directory in your project.
They consist mainly of text or HTML but any line can also contain special control statements.

 * Python commands can be used on lines beginning with a '%' sign
 (you can can use 'if'/'elif'/'else' or 'for' statements as you would do in Python)
 * You can include other templates: {{{&lt;%include file="header.html"/&gt;}}}
 * You can access attributes from your 'c' object used in the controller: {{{ ${ c.foo } }}}

See also [http://pylonshq.com/docs/template_plugins.html Template Language Plugins]

To use a template from a controller {{{return render_response('/templatefile')}}}.
Fill the attributes of the ''c'' object in your controller like this:

{{{#!python
class PingController(BaseController):
    def action(self):
        c.foo = 'Hello'
        c.bar = 'World'
        return render_response('/template.myt')
}}}

== Myghty templates ==

Mygthy is still the default templating system in Pylons 0.9.5. But as it likely that
it will be replaced by Mako I won't describe it here.

== Mako templates ==

=== Switch from Myghty to Mako ===

In the config/middleware.py you need to change the config.init_app call to:

{{{
config.init_app(global_conf, app_conf, package='yourproject', template_engine='mako')
}}}

In the config/environment.py you need to add these lines to use UTF-8 encoded templates correctly:

{{{
tmpl_options = {}
tmpl_options['mako.input_encoding'] = 'UTF-8'
tmpl_options['mako.output_encoding'] = 'UTF-8'
}}}

=== Differences Myghty -&gt; Mako ===

Variables in Mygthy were printed as {{{&lt;% c.foo %&gt;}}}.
In Mako you use {{{ ${ c.foo } }}} instead.

Python blocks in Mako are written in {{{ &lt;% my python code %&gt; }}}
but no result will be printed. If you want to display a return value
use {{{ ${ c.foo } }}}.

There is no automatic inheritance of the autohandler template. If you
want to use a global template you need to
{{{ &lt;%inherit file="/base.mako"/&gt; }}} it.

== Unicode ==

If your templates are utf-8 encoded you need to start all of your template files
with this line:

{{{
# -*- coding: utf-8 -*-
}}}

You should also config/environment.py's last line to:

{{{
    return pylons.config.Config(tmpl_options, map, paths,
        request_settings = dict(charset='utf-8', errors='replace') )
}}}

Otherwise you may get strange unicode errors. They showed up here when I used Formencode.

(See also: http://pylonshq.com/docs/0.9.5/internationalization.html#request-parameters)

= Sessions =

A session is used to store information of a current user sitting in front
of a web browser. HTTP is stateless so you usually don't know anything
about what the user did before the current HTTP request. With sessions you
are free to store and retrieve session data (variables in a dictionary) on the Pylons
web server. The user is tracked through a ''cookie'' that is associated to the
data dictionary by Pylons. To make that session information persistent the
variables set you set are saved in files under the data/sessions directory
(as specified in your development.ini -&gt; session_data_dir).

Example that increases the session variable ''testvalue'' every time a user
visits this URL:

{{{
from pylons import session

class ExampleController(BaseController):
    def index(self):
        if 'testvalue' in session:
            session['testvalue'] += 1
        else:
            session['testvalue'] = 0

        session.save()

        return Response('Current value is %s' % session['testvalue'])
}}}

= Webhelpers =

Webhelpers are a set of utility functions for Pylons documented at http://pylonshq.com/WebHelpers/module-index.html
You can use them to simplify AJAX calls, create HTML elements, control the script.aculo.us Javascript library and do
other fancy things. Your controllers can access the helpers through the global 'h' object.

&lt;!&gt; Note: The 'webhelpers' package consists of further sub-packages like 'htmlgen', 'util' or 'pagination'. These are not
imported automatically. Extend your lib/helpers.py by a line like "from webhelpers.rails import *" or rather "import webhelpers.rails" (keep your namespace clenaer) if you
want to use them. The 'rails' package is imported automatically.

Form example in a template that will submit the entered data to the same controller with a different action:

{{{
&lt;% h.form( url=h.url(action="dothat"), method='post' ) %&gt;
Please enter your name: &lt;% h.text_field(name='username', size=30) %&gt;
Your password: &lt;% h.password_field(name='password') %&gt;
Any comments? &lt;% h.text_area(name="usercomments", size="25x10") %&gt;
Where do you come from?
&lt;% h.select(name='origin', option_tags=h.options_for_select( [ ['Germany','GER'], ['Australia','AUS'] ] ) ) %&gt;
&lt;% h.submit(value='I am done') %&gt;
}}}

Further documentation:

 * Shell: pydoc webhelpers
 * Web: http://pylonshq.com/WebHelpers/module-index.html
 * Explore them using ipython as follows:

{{{
&gt; import webhelpers
&gt; webhelpers.[TAB]
&gt; webhelpers.url_for?
&gt; webhelpers.url_for??
}}}

 * Explore them in the paster shell... (ipython should be installed, too)

{{{
&gt; h.url_for?
}}}

= Logging/Debugging =

Use {{{h.log()}}} to write messages to the console you run ''paster serve'' on.
Redirect the output using: {{{paster serve - -log-file=yourlogfile development.ini}}}

= Global objects =

== ...in controllers ==

=== h ===

Webhelpers that come from ''lib/helpers.py''. Think 'h' as in ''Helpers''.

== ...in templates ==

=== c ===

Template variables. Think 'c' as in ''content''. Set them in your controller functions ({{{c.foobar = 42}}} and display them in your
templates using {{{&lt;% c.foobar %&gt;}}}.

=== m ===

The runtime context inside of ''Mygthy'' templates (see [http://www.myghty.org/docs/request.myt#request the request object])
Think 'm' as in 'Myghty'. See http://www.myghty.org/docs/request.myt#request

=== request.params ===

A dictionary that contains HTTP parameters.


= AJAX =

AJAX (''asynchronous Javascript and XML'') is a way to let your browser fetch new information from
a web server without reloading the whole page. Either that action is triggered by the click of
a submit button or just a timed action. What happens then is that the Javascript requests a certain
URL from the web server and replaces a defined part of the web page with the new content.

== Prototype / script.aculo.us ==

Pylons has built-in support for Javascript libraries:

 * [http://wiki.script.aculo.us/scriptaculous/show/Prototype Prototype][[BR]]
 Provides a lot of useful Javascript functions to be used in your web page.
 Pylons uses these functions to make using AJAX simpler.
 * http://script.aculo.us/[[BR]]
 Provides some visual effects that you can use to impress your coworkers.
 Not exactly needed to use AJAX but helps you use special form elements
 like a text input field that suggests auto-completion.
 scriptaculous is built upon Prototype and will not work without it.

Pylons even has these libraries bundled so you don't need to download them manually.
Just put

{{{
&lt;% h.javascript_include_tag(builtins=True)  %&gt;
}}}

into the {{{&lt;head&gt;}}} section of your templates/autohandler to load both libraries
on every HTML page.

== AJAX forms ==

One useful example of AJAX are HTML forms. You can alter the form
depending on what the user entered. The Webhelper's ''form_remote_tag''
function creates a {{{&lt;form&gt;}}} tag with some additional Javascript
that works together with Prototype/script.aculo.us.

{{{
&lt;% h.form_remote_tag(
    url=h.url(
        controller="list",
        action="reload_form"),
    id='my_form',
    method='post',
    loading=h.update_element_function(
        "loading",
        content='Loading... please wait...'),
    update='my_form'
    ) %&gt;

&lt;div id="loading"&gt;
&lt;/div&gt;

&lt;/form&gt;
}}}

This will create a {{{&lt;form&gt;}}} tag. The parameters mean:

 * url: the URL this form is submitted to (it calls the
 controller 'list' with the action 'reload_form')
 * id: the unique HTML identifier (id="...") of this HTML tag
 (each element of your HTML page can have one)
 * method: the method to send this form ('GET' or 'POST')
 * loading: a special action to run when the Javascript sent the
 AJAX request and awaits the answer from the web server. It tells
 the Javascript library to put ''"Loading... please wait..."''
 into the HTML element with the ID '''loading''' which is the
 {{{&lt;div&gt;}}} below the form. So while the user is waitint for the
 form to update itself through AJAX this message is shown.
 * update: tells the Javascript library to replace the HTML element
 with the ID ''my_form'' (our form itself) by whatever the web
 server returned

So you mainly need a controller 'list' that sends a HTML form
back. The Javascript receives what your controller prints and
will replace your HTML with that. So obviously your controller
needs to return just the form - not a full page with title
and header. That's why you need to tell the ''render_response''
function (that you use to print HTML based on templates)
to ''fragment'':

{{{#!python
return render_response('just_the_form.myt', fragment=True)
}}}

= SQLAlchemy =

Through the power of assign_mapper you get additional methods on your object classes
(see also http://www.sqlalchemy.org/docs/plugins.html#plugins_assignmapper).
To explore these methods and play with queries the "paster shell" is a good tool.
Install ipython, too, and you can TAB-complete and much more.

== Querying ==

(See also: http://www.sqlalchemy.org/docs/datamapping.html#datamapping_query_callingstyles)

 * model.Mymodel.get(15) [returns the row from the database table with the primary index 15]
 * model.Mymodel.get_by(me='good') [returns exactly one row]
 * model.Mymodel.select(model.Mymodel.c.religion=='atheism') [returns all matching rows as a list]
 * model.Mymodel.select_by(name='John') [returns all matching rows as a list]
 * model.Mymodel.count() [counts all rows of this model]
 * model.Mymodel.count_by(foo=51) [counts all rows matching this query]

The 'c' in .select() refers to the columns of that database table.

Specify the order of the results like this:

 * model.Mymodel.select(order_by=[model.Mymodel.c.name])

=== Incrementally adding criteria for a select request ===


{{{
query = model.DnsRecord.query()
query = query.filter(model.Mymodel.c.name.like('john%'))
query = query.filter(model.Mymodel.c.address.like('main st%'))
results = query.list()
}}}

''The .filter() method is not yet available as a method of the assign_mapper in version 0.3 of SQLAlchemy.
It will get added in version 0.4. Thus the {{{query()}}} in between. Additionally {{{filter_by()}}}
is not available in this context, yet.''


== Inserting new database rows ==

{{{
newmodel = model.Mymodel()
newmodel.name='John'
newmodel.gender='male'
newmodel.flush()
}}}

@@Only works with assign_mapper(). With mapper() either you had to use the SessionContextExt (http://www.sqlalchemy.org/docs/plugins.html#plugins_sessioncontext_sessioncontextext) or call newmodel.save(); newmodel.flush()

== Changing existing database rows ==

{{{
some_person = model.Mymodel.get_by(name='marc')
some_person.phone_number = '+81 576 47195'
some_person.flush()
}}}

== Many-to-many relationships with secondary mappings ==

If you use normalized tables (second or third normal form) you often need extra tables
that map IDs of one table to IDs of another table. Imagine you want to create a
bookmarking service and thus have tables for:

 * Users (ID, Name)
 * Bookmarks (ID, URL)
 * Mapping of User-ID to Bookmark-ID

The connection of users to bookmarks is done through the mapping table.
In SQL you need to join two tables to get all the bookmarks for a certain
user. SQLAlchemy simplifies that if you add a "secondary" property
(as described at
http://www.sqlalchemy.org/docs/datamapping.html#datamapping_manytomany).
This allows you to access the bookmarks linked to a certain user
directly as a property of the user object.
A table/object mapping that adds a secondary property looks like this:

{{{
mapper(User, users_table, properties = {
    'bookmarks':relation(Bookmark, secondary=bookmarks_table)
    } )
}}}

This adds a 'bookmarks' property to your
User objects. The property behaves like a list:

{{{
# Get John from the database
user_john = model.User.get_by(name='john')

# Print John's bookmarks
print user_john.bookmarks   # prints john's bookmarks
}}}

The last line looks up all matching rows in the User-ID-to-Bookmark-ID table
and fetches the bookmarks with the appropriate IDs.

{{{
# Create a new bookmark ("Bookmark" is a mapped class, too)
google = model.Bookmark.get_by(url='http://www.google.com')

# Add this bookmark to John
user_john.bookmarks.append(google)
}}}

The last statement inserts a new row into the User-ID-to-Bookmark-ID table
"connecting" this bookmark to John. Handy, isn't it?

== Unicode ==

=== MySQL ===

You should use two parameters when creating connections to MySQL databases
so that all fields are transmitted as unicode strings:

{{{
sqlalchemy.dburi = mysql://user:pass@localhost:3306/dbname?use_unicode=1&amp;charset=utf8
}}}

=== PostgreSQL ===

Define the fields in your table as ''Unicode'' instead of ''String'' and you should
get unicode strings all the time.

= Formencode =

todo...

Documentation for parameters of schemas: pydoc formencode.schema.Schema

formencode.validators.FancyValidator

prefill with defaults:
formencode.htmlfill.render(render('/hosts/new.mako'), defaults=request.params)


= AuthKit =

todo

Important: use different cookie names in your development.ini file for "session_key" and "authkit.cookie.name"

== Logging ==

In case AuthKit does weird things you can enable debugging by adding these lines to
your environment.py:

{{{
import logging
log_StreamHandler = logging.StreamHandler() # points to stderr
authkit.authenticate.log.addHandler(log_StreamHandler)
authkit.authenticate.log.setLevel(logging.DEBUG)
}}}

- - - - - - - - - - - -
paster shell -&gt; r = app.get('/') -&gt; r.req

http://code.google.com/p/modwsgi/

- - - - - - - - - - - - - - - - - - - -
websetup.py
paster setup-app --&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="python"></category></entry><entry><title>Elixir debaixo dos panos</title><link href="http://artigos.waltercruz.com/elixir-debaixo-dos-panos" rel="alternate"></link><updated>2008-05-13T13:33:32Z</updated><author><name>Walter Cruz</name><uri>http://waltercruz.com</uri></author><id>tag:artigos.waltercruz.com,2008-05-13:/elixir-debaixo-dos-panos</id><summary type="html">&lt;div class="document"&gt;
&lt;p&gt;Tradução de &lt;a class="reference" href="http://elixir.ematia.de/trac/wiki/BehindTheScene"&gt;http://elixir.ematia.de/trac/wiki/BehindTheScene&lt;/a&gt;&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a id="debaixo-dos-panos" name="debaixo-dos-panos"&gt;Debaixo dos panos&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Aqui está alguma explicação detalhada no que acontece nas entranhas do Elixir. Vamos usar o nosso exemplo do tutorial:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;using_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tablename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;movies&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Unicode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Repare que no texto a seguir, usarei os termos &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;entidade&lt;/span&gt;&lt;/tt&gt; e &lt;cite&gt;classe`&lt;/cite&gt; para referir-me a classe.&lt;/p&gt;
&lt;p&gt;Primeiro, quando a classe é declarada, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;using_options&lt;/span&gt;&lt;/tt&gt; é chamado e cada um desses três atributos é &amp;quot;interpretado&amp;quot; e três instâncias de &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Field&lt;/span&gt;&lt;/tt&gt; são criadas. Como using_options é um (uma instância de) ClassMutator (um tipo de decorador de classes usando métodos), tudo o que ele faz quando é chamado pela primeira vez é guardar os argumentos e argumentos de palavra chave com que foi chamado usando um atributo especial/oculto da classe &lt;a class="footnote-reference" href="#id3" id="id1" name="id1"&gt;[1]&lt;/a&gt; &lt;a class="footnote-reference" href="#id4" id="id2" name="id2"&gt;[2]&lt;/a&gt; . Você poderia perguntar: porque não agir diretamente? Bem, pela simples razão que nesse ponto, esses mutators não conhecem sobre a classe na qual são usados. Esses campos nem sabem que tem algo a ver com uma entidade de Filme.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id3" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1" name="id3"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;em &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;__elixir_mutators__&lt;/span&gt;&lt;/tt&gt; para aqueles que precisam saber.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2" name="id4"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;é feito usando alguns truques com a pilha de execução.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a id="metaclasse" name="metaclasse"&gt;Metaclasse&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Então, entra a metaclasse (EntityMeta. Entre outras coisas, ela:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;dá a oportunidade para que os ClassMutators atuem. Que significa que cada um dos class mutators para nossa classe serão processados. Ser processado, significa, no caso mais simples, que a função manipuladora registrada para o item é executada com os argumentos guardados[3]_. No nossos exemplo, isso irá resultar na seguinte chamada: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;using_options_handler(tablename=&amp;quot;movies&amp;quot;)&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;processa cada um dos atributos de classe, procurando por instâncias da classe Property e &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;amarrando-as&lt;/span&gt;&lt;/tt&gt; à entidade. Isso simplesmente chama o método &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;attach&lt;/span&gt;&lt;/tt&gt; em casa uma dessas propriedades, e dá a elas a habilidade de conhecer a qual entidade que elas pertencem e qual atributo elas &amp;quot;gerenciam&amp;quot;. Como a classe Field class é uma forma especializada (ela herda da) classe Property, nossos campos acima são incluídos nesse processamento. Ligar uma &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Property&lt;/span&gt;&lt;/tt&gt; à sua entidade tem ainda dois efeitos adicionais: o atributo é removido da classe (para não interferir com o sistema de gerenciamento de atributos do SQLAlchemy) ae registrado na lista de objetos &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;EntityBuilder&lt;/span&gt;&lt;/tt&gt; para essa entidade. Mais sobre isso a seguir.&lt;/li&gt;
&lt;li&gt;se a entidade é configurada com a opção &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;autosetup=True&lt;/span&gt;&lt;/tt&gt;, os gatilhos de setup são instalados.&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils footnote" frame="void" id="id5" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a name="id5"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Como nós frequentemente usamos handlers que fazem a mesma coisa, nós providenciamos alguns ClassMutators que fazem um pouco mais que apenas chamad o método handler.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a id="fase-de-configura-o" name="fase-de-configura-o"&gt;Fase de configuração&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Então vem a fase da configuração. Quando essa fase acontece depende da sua utilização ou não do autosetup, e se você usou o autosetup, quando você disparou um dos gatilhos. O objetivo da fase de configuraço é construir a tabela e o mapeador para suas entidades. Isso é feito chamando os entity builders e também alguns métodos da entidade em si (ou melhor, seu &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;descriptor&lt;/span&gt;&lt;/tt&gt; que é apenas um objeto criado para facilitar a fase de inicialização sem adicionar muitos métodos para a entidade em si).&lt;/p&gt;
&lt;p&gt;Agora, o que é um EntityBuilder? Citando a documentação da API:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Uma Entity builder é uma classe de objetos que podem ser adicionados em uma entidade (normalmente pelo uso de propriedades especiais ou declarações) que &amp;quot;constróem&amp;quot; essa       entidade . Construir uma entidade significa adicionar colunas à sua tabela principal, criar outras tabelas, adicionar proriedades ao seu mapeador, ... Para fazer isso, um EntityBuilder deve sobrescrever o(s) método(s) correspondente(s). Isso é para garantir que diferentes operações aconteçam na ordem correta (por exemplo, garantir que a tabela esteja totalmente criada antes que o mapeador que a usa seja definido).
&lt;/pre&gt;
&lt;p&gt;Por favor, olhe os métodos que EntityBuilders tem. A sequência exata de inicialização é atualmente como segue. Passos marcados com EB são feitos chamando o método correspondente &lt;a class="footnote-reference" href="#id7" id="id6" name="id6"&gt;[4]&lt;/a&gt; em todos os entity builders da entidade.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;setup_autoload_table&lt;/li&gt;
&lt;li&gt;create_pk_cols (EB)&lt;/li&gt;
&lt;li&gt;setup_relkeys (EB)&lt;/li&gt;
&lt;li&gt;before_table (EB)&lt;/li&gt;
&lt;li&gt;setup_table&lt;/li&gt;
&lt;li&gt;setup_reltables (EB)&lt;/li&gt;
&lt;li&gt;after_table (EB)&lt;/li&gt;
&lt;li&gt;setup_events&lt;/li&gt;
&lt;li&gt;setup_properties (EB)&lt;/li&gt;
&lt;li&gt;before_mapper (EB)&lt;/li&gt;
&lt;li&gt;setup_mapper&lt;/li&gt;
&lt;li&gt;after_mapper (EB)&lt;/li&gt;
&lt;li&gt;finalize (EB)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note que a sequência exata certamente mudará em versões futuras, já que o trabalho completo será feito por entity builders no futuro. O &lt;strong&gt;ponto importante&lt;/strong&gt; é que todos esses passos são feitos em ordem para todas as entidades de uma vez. Isso significa que o primeiro passo é feito para todas as entidades registradas, depois o segundo, e assim por diante.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id7" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id6" name="id7"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;O nome do método no entity builder não é sempre exatamente o mesmo, mas você pegou o espírito da coisa.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a id="todo" name="todo"&gt;TODO&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Related entities / classes lookup&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;To document briefly in tutorial and/or API docs if not already&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last simple"&gt;
&lt;li&gt;Inverse relationships matching&lt;/li&gt;
&lt;li&gt;Related entities / classes lookup&lt;/li&gt;
&lt;li&gt;M2M table&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="python"></category></entry><entry><title>Colocando os resultados do EXPLAIN em uma tabela</title><link href="http://artigos.waltercruz.com/postgresql/colocando-resultados-explain-tabela" rel="alternate"></link><updated>2008-05-04T11:03:51Z</updated><author><name>Walter Cruz</name><uri>http://waltercruz.com</uri></author><id>tag:artigos.waltercruz.com,2008-05-04:/postgresql/colocando-resultados-explain-tabela</id><summary type="html">&lt;div class="document" id="colocando-os-resultados-do-explain-em-uma-tabela"&gt;
&lt;h1 class="title"&gt;Colocando os resultados do EXPLAIN em uma tabela&lt;/h1&gt;
&lt;p&gt;Traduão de &lt;a class="reference" href="http://people.planetpostgresql.org/greg/index.php?/archives/106-Putting-EXPLAIN-results-into-a-table.html"&gt;http://people.planetpostgresql.org/greg/index.php?/archives/106-Putting-EXPLAIN-results-into-a-table.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Há uma &lt;a class="reference" href="http://groups.google.com/group/pgsql.hackers/browse_thread/thread/10f03e8c7f733588/7058771b9990a254"&gt;discussão na lista hackers&lt;/a&gt; sobre a explicação de planos, e alguém mencionou a idéia de guardar a informação do explain em rabelas. Isso me lembrou de uma pequena função &lt;a class="reference" href="http://www.postgresql.org/docs/8.2/static/plperl.html"&gt;Pl/Perlu&lt;/a&gt; que eu demonstrei como parte da minha palestra de Pl/Perl na PGcon. Eu estava usando-a para demonstrar um conceito em Pl/Perl, mas acabei usando outra função, então a função abaixo é ainda um rascunho sem polimento. Tavez alguém a ache útil de qualquer forma :-). A primeira coisa que precisamos é criar duas tabelas, uma que irá receber os resultados do explain de um plano, e a outra que irá conter todos os sub-elementos de cada plano:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;explain_result_id_seq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;explain_result&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;    &lt;span class="nb"&gt;INTEGER&lt;/span&gt;     &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;explain_result_id_seq&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;explain_result_id_pk&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;        &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cdate&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;explain_row&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;query&lt;/span&gt;        &lt;span class="nb"&gt;INT&lt;/span&gt;  &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;explain_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;orderin&lt;/span&gt;      &lt;span class="nb"&gt;SMALLINT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;indent&lt;/span&gt;       &lt;span class="nb"&gt;SMALLINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;action&lt;/span&gt;       &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cost_start&lt;/span&gt;   &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cost_end&lt;/span&gt;     &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;total_cost&lt;/span&gt;   &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;row1&lt;/span&gt;         &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;loop&lt;/span&gt;         &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;actual_start&lt;/span&gt; &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;actual_end&lt;/span&gt;   &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;total_actual&lt;/span&gt; &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;row2&lt;/span&gt;         &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;width&lt;/span&gt;        &lt;span class="nb"&gt;INTEGER&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora, a própria função, escrita em Pl/Perlu. Apenas passe uma declaração explain ou explain analyze, e a função irá executá-lo e tentar interpretá-lo, salvando o resultado nas tabelas. Ela retorna o id da linha inserida na tabela explain_result. Observe que essa função requer a versão 8.2 devido à &lt;a class="reference" href="http://www.postgresql.org/docs/current/interactive/sql-insert.html"&gt;cláusula RETURNING no INSERT&lt;/a&gt;, mas deve ser fácil modificá-la para funcionar com versões anteriores também.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;plp_explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RETURNS&lt;/span&gt; &lt;span class="n"&gt;TEXT&lt;/span&gt;
&lt;span class="n"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plperlu&lt;/span&gt;
&lt;span class="n"&gt;AS&lt;/span&gt; &lt;span class="nv"&gt;$_$&lt;/span&gt;

&lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="n"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$com&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$com&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="sr"&gt; /^\s*explain\s+/i&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="sx"&gt;qq{Not an explain query\n}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spi_exec_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$com&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$rv&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;eq&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;SPI_OK_UTILITY&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="sx"&gt;qq{Not a proper explain?\n}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$SPACER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{(\s*(?:-&amp;gt;)*\s*)}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$FLOAT&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{\d+\.\d+}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$COST&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{\(cost=($FLOAT)\.\.($FLOAT) rows=(\d+) width=(\d+)\)}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$ACTUAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{\(actual time=($FLOAT)\.\.($FLOAT) rows=(\d+) loops=(\d+)\)}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$ACTUALROW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{^$SPACER(.+)$COST\s*$ACTUAL$}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$COSTROW&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{^$SPACER(.+)$COST$}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$RAWROW&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;qr{^$SPACER(.+)\s*$}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;## Returning needs 8.2&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$SQL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;INSERT INTO explain_result(query) VALUES ($1) RETURNING id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$sth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spi_prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$SQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spi_exec_prepared&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$com&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$res&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;$SQL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;INSERT INTO explain_row&lt;/span&gt;
&lt;span class="s"&gt;(query,orderin,indent,action,cost_start,cost_end,total_cost,row1,loop,actual_start,actual_end,total_actual,row2,width)&lt;/span&gt;
&lt;span class="s"&gt;VALUES ($id&lt;/span&gt;
&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$orderin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;QUERY PLAN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$rv&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="sr"&gt; /$ACTUALROW/&lt;/span&gt;
                &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="sr"&gt; /$COSTROW/&lt;/span&gt;
                &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="sr"&gt; /$RAWROW/&lt;/span&gt;
                        &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Cannot parse explain row: $row&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$indent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$row1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$a1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$a2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$row2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defined&lt;/span&gt; &lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$row1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defined&lt;/span&gt; &lt;span class="nv"&gt;$7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$a2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$row2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;$action&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;s/&amp;#39;/&amp;#39;&amp;#39;/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;$SQL, $orderin,&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$orderin&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$sql&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;length&lt;/span&gt; &lt;span class="nv"&gt;$indent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sx"&gt;qq{,&amp;#39;$action&amp;#39;,$c1,$c2,0,$row1,$loop,$a1,$a2,0,$row2,$width)}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;spi_exec_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sql&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Explain plan stored as id $id\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="vg"&gt;$;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O uso é dessa forma:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;plp_explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$$&lt;/span&gt;
  &lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;nspname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pg_size_pretty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pg_relation_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_class&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pg_namespace&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relnamespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oid&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;relkind&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;i&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;pg_relation_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
  &lt;span class="n"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Take a look at the results:&lt;/span&gt;

&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;explain_result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;explain_row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Poderia certamente ser um pouco mais refinado, por exemplo, interpretando e separando em seções conhecidas (Hash, Seq Scan, etc.) mas é um bom início até que o Postgres desenvolva uma funcionalidade similar nativamente.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="perl"></category></entry><entry><title>Do PHP Para Lua</title><link href="http://artigos.waltercruz.com/dophpparalua" rel="alternate"></link><updated>2008-05-02T16:33:11Z</updated><author><name>Walter Cruz</name><uri>http://waltercruz.com</uri></author><id>tag:artigos.waltercruz.com,2008-05-02:/dophpparalua</id><summary type="html">&lt;div class="document"&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a id="motiva-o" name="motiva-o"&gt;Motivação&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Foi em 1999 que, pela primeira vez, ouvi falar em Software Livre. Nessa mesma época, tive meus primeiros contatos com Linux, PHP e Javascript, que hoje são minha ferramenta de trabalho.&lt;/p&gt;
&lt;p&gt;Somente em 2001, dois anos depois, ouvi falar na linguagem Lua. Eu trabalhava na Netage (uma empresa de informática). O Alfredo (na ocasião, colega de trabalho) mencionou, entre outras coisas, Python e Lua. De lá pra cá, todos os meus planos de aprender Python foram frustrados. Ao contrário de Lua, que reapareceu na minha vida há pouco tempo.&lt;/p&gt;
&lt;p&gt;No início deste ano (2005), peguei algumas coisas em PHP para fazer. Como não tinha - e ainda não tenho - micro em casa, fazia muitas coisas em cyber. Como precisava de algo melhor que o Notepad, pequeno, fácil de baixar e instalar em qualquer lugar, acabei conhecendo o &lt;a class="reference" href="http://www.scintilla.org/SciTE.html"&gt;Scite&lt;/a&gt;, que hoje é meu editor de textos padrão.&lt;/p&gt;
&lt;p&gt;Um dos principais usos de Lua é como uma linguagem embutida em outras aplicações. Entre elas, estão o &lt;a class="reference" href="http://elinks.or.cz/"&gt;elinks&lt;/a&gt; (um navegador em modo texto), uma porção de jogos da &lt;a class="reference" href="http://www.lucasarts.com/"&gt;LucasArts&lt;/a&gt; e, como você já deve ter adivinhado, o SCite.&lt;/p&gt;
&lt;p&gt;Foi assim que eu encontrei, de fato, a linguagem Lua: tentando fazer alguns scripts para o SCite. Como dizem, &amp;quot;a necessidade é a mãe da invenção&amp;quot;.&lt;/p&gt;
&lt;p&gt;Como eu estou habituado com PHP, prossigo falando de Lua pressupondo que você já conheça um pouco de PHP.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a id="semelhan-as" name="semelhan-as"&gt;Semelhanças&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h1&gt;&lt;a id="tipagem-din-mica" name="tipagem-din-mica"&gt;Tipagem dinâmica&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Em PHP e Lua (assim como na maioria das linguagens de script), não é necessário declarar o tipo de variável. Tanto PHP como Lua fazem coerção (conversão automática entre tipos de variáveis). Assim, temos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--Conversão de tipos em Lua&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--number&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;5&amp;quot;&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;-- string&lt;/span&gt;
&lt;span class="n"&gt;soma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;soma&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- 10&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;soma&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;--number&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- string (55)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="c"&gt;//Conversão de tipos em PHP&lt;/span&gt;
&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;gettype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;//integer&lt;/span&gt;
&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;gettype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;//string&lt;/span&gt;
&lt;span class="nv"&gt;$soma&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$soma&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;//10&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;gettype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$soma&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c"&gt;//integer&lt;/span&gt;
&lt;span class="nv"&gt;$concatenacao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$concatenacao&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;//55&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;gettype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$concatenacao&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c"&gt;//string&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Outro exemplo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Retorna 3. Mas&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;texto&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Retorna 2, sem informar nada.&lt;/p&gt;
&lt;p&gt;Em Lua:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;walter&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;walter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;~&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;devel&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;waltercruz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;artigos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dophpparalua&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;lua&lt;/span&gt;
&lt;span class="n"&gt;Lua&lt;/span&gt; &lt;span class="mf"&gt;5.0.3&lt;/span&gt;  &lt;span class="n"&gt;Copyright&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;1994&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2006&lt;/span&gt; &lt;span class="n"&gt;Tecgraf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PUC&lt;/span&gt;&lt