Publicado em linux, python, turbogears

SQLAlchemy no TurboGears

Depois de tempos postando sobre política posso dizer que estou voltando a ativa novamente. Neste post trataremos de um assunto que nunca mais havia tocado: TurboGears.

A minha framework web favorita escrita em Python está na versão 1.0.2.2 e correndo para a versão 1.1, principalmente depois de um sprint que ocorreu recentemente. Os desenvolvedores substituirão o sistema de templates Kid pelo Genshi e o SQLObject pelo SQLAlchemy. O que posso dizer é que podemos usar o SQLAlchemy atualmente sem muitos problemas. Constatei isso implementando um exemplo bem conhecido em Ruby on Rails: um livro de receitas eletrônico (cookbook em inglês).

Vamos mostrar algum código, uma vez que isso é mais divertido. Precisamos do TurboGears e do SQLAlchemy:

easy_install -U TurboGears
easy_install SQLAlchemy

Antes de criarmos uma infraestrutura para o projeto, gostaria que vocês conseguissem o servidor de banco de dados MySQL. Vamos fazer o nosso exemplo de acordo com o do Rails. Se vocês quisserem fazer o mesmo exemplo em Rails sugiro lerem alguns posts do blog do Brasília on Rails. Vamos criar nosso banco de dados com o seguinte comando num terminal bash do Linux:

$ mysql -u root -p
> create database cookbook;
> grant all on cookbook.* to 'usuario@localhost';

O esquema do banco é o seguinte:

drop table if exists recipes;
drop table if exists categories;
create table categories ( id  int  not null auto_increment,
    name varchar(100)   not null default '',
    primary key(id)
) engine=InnoDB;

create table recipes ( id int  not null auto_increment,
     category_id int not null,
     title varchar(100)   not null default '',
     description varchar(255)   null,
     date  date null,
     instructions text  null,
     constraint fk_recipes_categories foreign key (category_id) references categories(id),
     primary key(id)
) engine=InnoDB;

Colem este esquema num arquivo (digamos, create.sql) e executem:

mysql cookbook < db create.sql

Feito isso, vamos ao TurboGears:

tg-admin quickstart --sqlalchemy

Chamarei o projeto de cookbook. Selecionem ‘não‘ quando perguntado se querem usar o Identity.

Dentro da pasta do projeto há o arquivo dev.cfg para as configurações no ambiente de desenvolvimento. Lá informaremos à aplicação a string de conexão:

sqlalchemy.dburi="mysql://root:oinc@localhost/cookbook"

Executemos o script start-cookbook.py para rodar o servidor. Depois acesse o endereço http://localhost:8080/ para testar a aplicação.

python start-cookbook.py

Depois disso, vamos no arquivo cookbook/model.py para mapear para objetos o nosso banco com SQLALchemy:

from sqlalchemy import *
from turbogears.database import metadata, session, bind_meta_data
#from sqlalchemy.ext.assignmapper import assign_mapper

bind_meta_data()

categoria_tabela = Table('categories',metadata,autoload=True)

receita_tabela = Table('recipes',metadata,autoload=True)

class Categoria(object):
    def __init__(self,name):
        self.name = name
    def __repr__(self):
        return self.name

class Receita(object):
    def __init__(self,title):
        self.title = title
    def __repr__(self):
        return self.title
    def nome_categoria(self):
        return self.categoria.name

mapper(Categoria, categoria_tabela, properties={'receitas' : relation(Receita,backref='categoria')})
mapper(Receita, receita_tabela)

Para o post não ficar muito grande, faremos somente uma página que lista todas as receitas. Eu não cheguei a implementar todo o exemplo do Cookbook, no entanto é muito mais do que mostrarei para vocês daqui pra frente. Como não tenho nenhum local na internet para disponibilizar este exemplo, vocês terão de informar e-mail para que eu envie-os.

Copiem o template welcome.kid e criem o arquivo receita_list.kid. Retirem o corpo da página e coloquem somente o seguinte:

${grid.display(receitas)}

Editem o arquivo cookbook/controllers.py. Escreveremos um método que acesse o banco de dados para pegar todas as receitas e passe essa lista para o template que criamos.

@expose(template="cookbook.templates.receita_list")
def receitas(self):
    receitas = session.query(Receita).select()
    grid = DataGrid(fields=[('Nome','title'), ('Categoria',Receita.nome_categoria)])
    return dict(receitas = receitas, grid = grid)

Para que esse método funcione, temos de importar model.py e widgets.DataGrid.

from model import *
from turbogears.widgets import DataGrid

A primeira linha do método utiliza o objeto session para fazer uma consulta no banco na tabela recipes (mapeada pela classe Receita). Na segunda linha, instanciamos o DataGrid que será usado para gerar a tabela de resultados. Por fim, a última declara os objetos que serão usados em nosso template.

Acessemos a URL http://localhost:8080/receitas. Espero que tenha funcionado! 😉 Problemas e dúvidas, por favor, comentem.

Atualização: Baixem a aplicação. Oferecimento: Walter Cruz 😉

Anúncios

10 comentários em “SQLAlchemy no TurboGears

  1. Porque você não sou metadata.create_all() depois de ter definido as tabelas no model? Eu sempre prefiro fazer assim, me livra de escrever SQL, fica mais fácil de fazer modificações e elimina o (pequeno) processamento requerido pra introspecção…

  2. Olá, Geron!

    Eu simplesmente não usei o método que sugeriu porque copiei o código SQL do exemplo do cookbook do Rails, enfatizando o fato de estar escrevendo em TurboGears algo já feito para outro framework.

    Valeu o comentário!

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s