Django Brasil


Comunidade brasileira de Django


Feeds RSS

Envolva-se

O Django Brasil é um grupo de usuários e pesquisadores brasileiros de Django, uma framework para desenvolvimento ágil para a Web, baseada na linguagem Python e em padrões da programação orientada a objetos.

Listas de discussão

  • Usuários do Django no Brasil: Lista de discussão de ajuda ao Django em português.

    Inscreva-se na lista Django-Brasil
  • django-l10n-portuguese: Equipe de localização e tradução do Django para o português.

    Iscreva-se na lista de localização

Diga ao mundo

Obtenha ajuda

Autores

Você escreve sobre Django em português? Avise-nos, e adicionaremos seu feed nesta página.

Comunidade

Esta página é atualizada a cada hora e agrega entradas dos blogs de brasileiros que escrevem sobre o Django.

Lançada a versão 1.0 alpha 2

Publicado em 09/08/2008 às 2h55
Marinho Brandão feed

Atenção: este artigo foi escrito para ser lançado no blog da DjangoBrasil [8] porém, por motivos técnicos, ele está sendo publicado aqui e será republicado lá dentro de algumas horas.

"Fantástica" é a palavra mais apropriada para esta última release, lançada ao final do dia desta sexta-feira.

A nova release, mais um passo da fiel agenda rumo à versão 1.0 final foi anunciada [1] com 4 novidades de tirar o fôlego, além das centenas de correções e ajustes efetuadas ao longo das últimas duas semanas:

Signals refactoring

O sistema de signals foi redesenhado em sua totalidade, o que rendeu um resultado assombroso de 90% de melhora na performance. A forma de escrever signals agora mudou, e também mudou - ainda que permaneça suportando a forma antiga - a forma de conectar funções a signals. Veja mais detalhes em [2] .

Fica aqui uma atenção especial sobre o django-tagging, django-ads, djapian e outras aplicações plugáveis que fazem uso de signals próprios.

GeoDjango

O branch para fazer o Django suportar GIS [3] foi finalizado e inserido ao trunk, destacado pela contrib django.gis. Essa novidade possibilita a criação de soluções baseadas em bancos de dados geográficos usando Django, o que dá um poder realmente grande ao framework.

Armazenamento de arquivos extensível

Esta novidade pode ser vista com detalhes em [4]. Agora é possível se criar backends para tratar o armazenamento de campos baseados em arquivo - especialmente FileField e ImageField - o que agora possibilita o armazenamento em banco de dados, locais remotos e em servidores de cloud computing de uma forma mais conceitualmente correta, sem necessitar de armazenamentos temporários com transferências.

Aqui vale um cuidado especial e bons testes antes de migrar seu site ou sistema em produção, é provável que necessite de ajustes.

Compatibilidade com Jython

A novidade também recente [5] da versão 2.5 do Jython e os ajustes feitos no Django para esta release agora permitem rodar um projeto baseado em Django usando a Java Virtual Machine e explorar assim sua robustez.

Outra melhoria conquistada nesta release é a de performance no suporte à internacionalização, que foi ajustado e otimizado. Diversas observações de incompatibilidade surgidas das últimas novidades podem ser encontradas em [6].

Continuamos em grade expectativa para a versão 1.0-final e sempre muito gratos à equipe de desenvolvedores [7], testadores e lançadores de tickets.

Links relacionados

[1]http://www.djangoproject.com/documentation/release_notes_1.0_alpha_2/
[2]http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges#Signalrefactoring
[3]http://geodjango.org/
[4]http://www.djangoproject.com/documentation/files/
[5]http://fwierzbicki.blogspot.com/2008/07/jython-25-alpha-released.html
[6]http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
[7]http://code.djangoproject.com/browser/django/trunk/AUTHORS
[8]http://djangobrasil.org/

Leia essa entrada em seu contexto original »

Tema do Django para GNOME

Publicado em 01/08/2008 às 17h22
semente feed

Eu utilizo no meu GNOME o tema Clearlooks acho que desde que ele foi lançado. Tentei utilizar outros, mas nunca me acostumei.

Depois que o grande pixel-artista Jader Rubini, fez um lindo fundo de tela para a comunidade Django Brasil, eu dei uma uma pequena personalizada no Clearlooks e o chamei de Django. E por que não? Tem as mesmas cores comumente utilizadas pelo Projeto Django.

Eu achei que o conjunto (fundo de tela, clearlooks e cores) ficou bonito e agradável. Dê uma olhada:

Foto da área de trabalho do semente

Minha área de trabalho.

Se gostou também, você pode obtê-los nos links abaixo:


Comentários | Link permanente
Etiquetas: arte, clearlooks, django, djangobrasil, fundodetela, gnome, jaderrubini, tema
© Guilherme M. Gondim, 2008. Termos de Uso

Leia essa entrada em seu contexto original »

Qual é a melhor IDE para Django?

Publicado em 01/08/2008 às 12h54
Marinho Brandão feed

Há tempos que venho mantendo o IMHO ligado a 100% quando este assunto é tocado por alguém pessoalmente ou na comunidade, mas enfim, resolvi tira-lo do OFF para este artigo, já que a sensação na realidade é de saco cheio com esse assunto.

Longe de querer evangelizar pessoas a usarem o gVim [1] (veja também a lista de editores para Python [2]), a minha intenção aqui é alertar quanto à ilusão que se tem com IDEs e editores, focando em seus recursos preguiçosos no lugar de em suas ferramentas para produtividade real.

Há uma visão distorcida generalizada quanto à palavra produtividade. A máxima foi evoluída por ferramentas consideradas "produtivas", como Delphi, Visual Basic, Access e outras ferramentas menos populares onde a competição sempre foi oferecer mais e mais recursos prontos, movimentos de mouse, ferramentas visuais e code-templates.

Ocorre que à época que essas ferramentas foram criadas as alternativas eram Clipper, DataFlex, FoxPro e até mesmo Cobol, e na febre do marketing da mudança do ambiente console para ambiente gráfico, foi criada a ilusão de que tudo que é visual é mais rápido e produtivo que em modo texto.

Doce ilusão.

Uma ferramenta como o Delphi, com milhares de itens no menu e seus complementos é tão fácil de operar quanto o painel colorido e piscante de um Boeing 747 na cabina do piloto. E o pior: o avião está caindo.

Obviamente, não há comparações entre uma ferramenta exageradamente visual a alguns recursos de editor. Mas a premissa é a mesma, com dosagens diferentes.

Mas vamos supor que você goste de autocomplete, um dos recursos mais cosiderados quando se procura um editor.

A cada vez que você precisar digitar um import, basta digitar os primeiros caracteres e o editor irá exibir uma caixa de seleção com alternativas com o mesmo prefixo e você irá escolher uma das opções.

Isso reserva pelo menos quatro reflexões (reserve pelo menos 1 minuto para cada ponto abaixo):

A quantidade de vezes que você pressionou uma tecla é realmente menor que a necessária para digitar a expressão manualmente?

O trabalho de levar o braço até o mouse de forma a escolher a opção desejada é realmente menor que o trabalho de digitar a expressão manualmente?

Se fosse em uma situação em um editor sem esses recursos (no servidor, por exemplo), você conseguiria digitar essa expressão sem dificuldade?

A memória, processador e leitura no HD de forma a indexar, localizar e exibir as alternativas é tão curta que compense a espera?

Refletiu?

Agora leia este meu caso: todas as vezes que eu precisava escrever um signal, eu copiava o bloco de codigo com uma linha de comentário, 2 imports e algumas linhas com um signal qualquer de algum arquivo já pronto e fazia as modificações. Consequência: eu nunca sabia fazer isso sozinho, eu não me lembrava da lógica de funcionamento dos signals, e simplismente não sabia onde no código do framework estariam os signals de models, o que atrapalhava meu raciocínio sobre como os signals funcionam.

Tomei a seguinte medida: parei de fazer isso, nas primeiras vezes eu escrevi algumas coisas erradas mas fui acertando mais e mais até isso se tornar uma tarefa rotineira e então eu consegui ter uma visão ampla de como os signals funcionam e como eles estão modularizados.

Parece bobo, mas é assim mesmo que funciona. E cá entre nós: você acha mesmo que procurar um arquivo, abrí-lo e copiar um bloco de codigo semelhante ao que eu precisava era mais produtivo e mais rápido do que digitar manualmente?

DRY fala das coisas que devem ser feitas de forma reutilizável, não do seu hábito em copiar essas coisas e espalhar códigos semelhantes e mal pensados pela aplicação. E DRY também não se trata de ter preguiça de pensar, na verdade DRY existe para distribuir as coisas de forma clara de forma que você possa pensar mais amplamente, mas sem se esquecer da essência.

Agora, para finalizar: qual é o editor ou IDE ideal para se trabalhar com Django?

Isso - claro - vai depender de seu gosto pessoal, mas ao instalá-lo, desabilite todos os recursos criados para preguiçosos e use o que ele tem de melhor: teclas de atalho, abas, buscas por regex, integrações com software de versionamento e o que mais tiver. Faz bem para você.

E também não é demais ressaltar: com um raciocínio rápido e bom conhecimento em profundidade, sua produtividade estará relacionada à rapidez que você consegue criar a solução e não na rapidez que consegue escrever uma gambiarra ;)

[1]http://www.vim.org/
[2]http://www.pythonbrasil.com.br/moin.cgi/IdesPython

Leia essa entrada em seu contexto original »

Lista de discussão Django Apps

Publicado em 31/07/2008 às 11h01
semente feed

O Michael Elsdörfer criou a lista de discussão Django Apps. A idéia é utilizar a lista para suas próprias aplicações Django e isso possui, no mínimo, duas grandes vantagens:

  1. Se faz desnecessário a criação de uma lista de discussão para cada nova aplicação;
  2. Existe uma potencial possibilidade de outras pessoas, não necessariamente usuárias de suas aplicações, participarem das discussões com ótimas opiniões.

Eu não iria criar listas de discussões para minhas aplicações, uma vez que o número de discussões tenderia à zero e seria uma tarefa chata, mas, com isso, as aplicações Diário, Fleshin e Tube ganharam um local para discussão!

Então, quando precisar, já sabe onde pode discutir algo a respeito das aplicações citadas acima. Já adicionei o grupo de discussão nas páginas dos meus projetos no Google Code. Utilize o prefixo [diario], [fleshin] e [tube] no assunto das mensagens, como descrito na página inicial do grupo:

All messages should be prefixed with the application name in brackets. If the application name itself has the popular django prefix, it should be left off. E.g. use [tables] for django-tables.

Comentários | Link permanente
Etiquetas: apps, diario, django, fleshin, listadediscussão, tube
© Guilherme M. Gondim, 2008. Termos de Uso

Leia essa entrada em seu contexto original »

Oportunidade de trabalho em Barueri-SP

Publicado em 30/07/2008 às 21h00
Marinho Brandão feed

O Rudá enviou a seguinte mensagem:

Oportunidade de trabalho para programador(a) trainee Python

Segue os detalhes de vaga

Conhecimentos Necessários: Python, HTML, CSS, JavaScript, SQL

Conhecimentos Desejáveis: Django, Zope, Plone, PostgreSQL, MSSQL Server, Linux

Empresa: Mondial Eletrodomésticos (www.mondialline.com.br)

Local de trabalho: Alphaville, Barueri - SP

Carga horária: de 6 a 8 hs.

Salário variando de R$ 1.500,00 à 2.500,00, dependendo da carga horária e do conhecimento do candidato.

Foco de trabalho: análise de requisitos e desenvolvimento de aplicação web gerencial para extração de relatórios de faturamento/produção/custos.

Obs: a vaga inicialmente é temporária (4 a 6 mêses) mas existe chance de efetivação

Interessados favor enviar CV com pretensão salarial para: ruda em mondialline ponto com ponto br

Leia essa entrada em seu contexto original »

Oportunidade de trabalho em Fortaleza

Publicado em 30/07/2008 às 17h00
Marinho Brandão feed

O Nicholas enviou o seguinte anúncio:

a gNial está contratando 1 (um) programador para atuar em Fortaleza-Ceará que possua os seguintes conhecimentos:

* Python
* Django
* XML

Desejável:

* FreeSwitch

Salário de acordo com o perfil.

Favor enviar currículo para nicholas em gnial ponto com ponto br

Veja também

http://gnial.com.br/

Leia essa entrada em seu contexto original »

Agora com domínio novo

Publicado em 25/07/2008 às 21h00
Marinho Brandão feed

Before all, an english resume: my apologizes for the recent duplicates of entries in Django Community site. This ocurred because I changed the permalinks to slugs (they was id-based) and now I changed the domain. But I promise this won't happen again for the near time :)

Bom, quem assina os feeds do blog (algo em torno de 50 pessoas diretamente, mais os assinantes do Django Brasil Planeta e do Django Community) deve ter notado uma anomalia nos últimos dias:

Por duas vezes, os artigos tiveram seus permalinks alterados (a primeira vez por conta dos slugs e a segunda por conta do domínio), e como o permalink é a chave única para os leitores RSS, isso fez com que os últimos 20 artigos fossem contados como novos.

Acontece que agora estou de domínio novo: http://marinhobrandao.com/ e isto causou o rebuliço pela segunda vez.

Então ficam aqui meu sincero pedido de desculpas pelo ocorrido e também o pedido para que anote o novo endereço.

Todas as URLs do antigo endereço estão apontadas para as respectivas no novo endereço, com redirect permanente de código 301, portanto, tudo continua funcionando normalmente, mas é recomendável utilizar o novo endereço :)

Leia essa entrada em seu contexto original »

Uma conversa sobre Django e tudo mais, no Café com TOM

Publicado em 25/07/2008 às 8h23
Andrews Medina feed

Sábado, dia 26 de Julho a convite do meu amigo Carlos, estarei apresentando o Django no Café com TOM numa conversa bem bacana e descontraída.

Se você não sabe o que é o Django, está afim de conhecer. Ou se você já conhece o framework mas quer saber mais? Ou apenas está sem fazer nada no sábado e quer fazer algo bem nerd, participe você também do Café com TOM.

Não esqueça de trazer a coca-cola.

Leia essa entrada em seu contexto original »

Lançada a versão 1.0 alpha

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Ontem ao fim do dia foi anunciada a versão 1.0 alpha [1], que é o primeiro passo para a release 1.0 final, a ser lançada em setembro, na DjangoCon.

A maior parte das features da versão 1.0 tem sido utilizada há meses (algumas há anos) através da versão trunk, pois havia muito tempo que a versão 0.96 foi liberada e a maior parte dos desenvolvedores usam a versão do trunk em produção.

O que podemos destacar nesta versão

  • Suporte a Unicode - a versão anterior não era 100% unicode, o que gerava algumas dificuldades na implantação e distorções entre máquina de desenvolvimento e servidor em produção. Essa feature mudou definitivamente o nosso trabalho pois a partir do momento em que ela foi liberada no trunk, deixamos de nos preocupar com codificação de caracteres e o trabalho passou a render mais.
  • Escape como default nas variáveis no template - esta feature fez uma diferença fundamental na segurança das aplicações, uma inversão pequena que melhorou bastante os resultados dos projetos.
  • ORM refatorado com heranças de modelo - há 2 ou 3 meses essa feature foi liberada, possibilitando trabalhar com heranças de classes de modelo, tanto de forma abstrata quanto de forma distribuída em tabelas, isso possibilita que você tenha classes de modelo que são baseadas em outras e seus dados são exibidos de forma transparente.
  • Admin baseado em NewForms - a última grande novidade, liberada no último sábado foi o merge do branch newforms-admin, que traz consigo todo o Admin refatorado para ser modular e compatível com NewForms. Assim, todo o acoplamento entre classes de modelo e admin foi removido e foi definido um módulo admin.py para conter as classes e definições da aplicação para o Admin. Com o novo admin é possível trabalhar de forma muito mais profissional com sistemas diversos, customizar sua interface de administração do site, adicionar recursos de Ajax, etc.

As próximas versões a serem lançadas na programação da 1.0 serão: 1.0 beta 1, 1.0 beta 2, 1.0 RC 1, 1.0 RC 2 e finalmente, a 1.0 final, prevista para o dia 2 de setembro, na DjangoCon.

Vantagens da versão 1.0

A versão 1.0 é anciosamente esperada pois com o crescimento exorbitante do framework neste último ano fez com que ele ultrapassasse a fronteira técnica, chegando até os diretores de tecnologia, empresários e grandes empresas. Desta forma, uma versão padrão vai permitir uma melhor profissionalização do uso do framework, tanto no uso do Google App Engin [2] quanto no treinamento de profissionais, edição de livros, redação de cursos, etc.

Links relacionados

[1]http://www.djangoproject.com/documentation/release_notes_1.0_alpha/
[2]http://code.google.com/appengine/

Leia essa entrada em seu contexto original »

Load balancing e Cache com MySQL Proxy

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Que tal aprender uma nova linguagem enquanto faz uma boa tarefa para melhorar a escalabilidade do banco de dados?

Bom, foi isso que eu fiz hoje durante quase todo o dia. Descobri no início do dia que Lua é a linguagem de script do MySQL Proxy e mergulhei pra fazer duas coisas bastante interessantes: Load Balancing e Cache de resultados.

Load Balancing

Eu conheço 3 formas de fazer load balancing com MySQL:

  • MySQL Cluster [1]
  • MySQL Proxy [2]
  • MySQL Master/Slave [3]

Mas na verdade não conhecia em profundidade nenhum deles, apenas uma idéia superficial.

No final de semana testei o Master/Slave. Parece ser o mais poderoso dentre os três métodos, mas usá-lo no Django significa mexer em boa parte do código do ORM. Não é a minha intenção. Cheguei a construir um backend pra isso, em cima do backend do MySQL, e até descobri que havia outro semelhante [4]. Mas nem o meu backend improvisado, nem o do Ivan Sagalaev me seduziram: muito limitado e cheio de falhas de design.

Pois bem, o MySQL Cluster também me desanimou depois que eu li diversos depoimentos contrários [5].

Sobrou o MySQL Proxy.

MySQL Proxy

Este é um software um tanto recente da MySQL, que basicamente faz a ponte entre o(s) servidor(es) de MySQL e a sua aplicação. É vantajoso pois é independente de linguagem ou framework: você desenha as regras e o que vem depois delas pouco importa, funciona da mesma forma.

http://marinho.webdoisonline.com/blog/p/diagrama_mysql_proxypng_172/?img=1

Não quero explicar como instala e usa este software, portanto vou me limitar ao script que montei para fazer load balancing. Não foi devidamente testado e em algumas situações foi exibido o erro (1105, '#07000(proxy) all backends are down'), portanto, antes de ir migrando seu servidor, faça muitos testes e verifique mais detalhes.

O script, feito em Lua, ficou assim

function connect_server()
    local num = tonumber(os.date("%S")) % 2
    proxy.connection.backend_ndx = num + 1
    print("Using " .. proxy.backends[proxy.connection.backend_ndx].address)
end

Salve o arquivo como load_balancing.lua e execute da seguinte forma:

mysql-proxy \
    --proxy-lua-script=load_balancing.lua \
    --proxy-backend-addresses=127.0.0.1:3306 \
    --proxy-backend-addresses=vs2:3306

O parâmetro --proxy-backend-addresses pode ser repetido quantas vezes quiser, um para cada réplica do MySQL, quanto mais réplicas, mais poderoso é o seu "cluster".

Os hosts "127.0.0.1" e "vs2" são respectivamente, minha máquina e uma máquina virtual rodando no vmware-server, portanto, use os IPs ou hostnames conforme a sua realidade.

Ele não suporta master/slave (não encontrei nada na documentação que orientasse como fazer nesse caso), portanto foi necessário configurar os hosts como master/master, que você pode ver como fazer em [6]

O funcionamento é assim: nos segundos pares as conexões são repassadas ao servidor 1, e nas ímpares as conexões são repassadas para o servidor 2. Se houvessem 10 servidores, o módulo de 2 (local num = tonumber(os.date("%S")) % 2) seria feito com 10 (local num = tonumber(os.date("%S")) % 10) e o comando de chamada do mysql-proxy teria 10 vezes o parâmetro --proxy-backend-addresses. Simples né?

Cache em memória

Bom, eu já havia feito o mesmo tipo de coisa hackeando a QuerySet e criando o método .cache() [7], que me ajudou muito. Esta solução que eu criei hoje pode ser considerado inferior à anterior por oferecer menos granularidade e funcionar somente com MySQL, mas caso você não queira modificar o código original do Django, esta pode ser uma boa alternativa para você.

Este segundo script funciona da seguinte forma: quando uma consulta do tipo SELECT é feita ao banco de dados, seu resultado é armazenado em um servidor Memcached, com tempo de expiração definido por pattern (cada pattern, ou seja, cada modelo de SELECT pode possuir um tempo de expiração diferente) e se uma cosulta idêntica for requisitada dentro do tempo de expiração, o servidor de cache será consultado, ao invés do banco de dados.

Bacana né?

Então lá vai

-- Packages required
require("Memcached") -- http://luamemcached.luaforge.net/
require("json")      -- http://www.chipmunkav.com/downloads/Json.lua

-- Connect to memcached server
local conn = Memcached.Connect('localhost', 11211)

-- Default expire time for cache items
local default_expire_time = 30

-- Prefix for cache keys
local key_prefix = 'mysql-proxy-'

-- Patterns to define expiration time for different types of queries.
-- More details in: http://lua-users.org/wiki/PatternsTutorial
local patterns_expire_time = {
    {'^%s*select .+from .*auth_user', 150},
    {'^%s*select', default_expire_time},
}

-- Converts a string to valid key
function encode_key(str)
    return key_prefix .. string.gsub(str, ' ', '-')
end

-- Converts a resultset to JSON. This can't be done by
-- Json library directly because it's a userdata datatype
-- instance
function resultset_to_str(resultset)
    local rfields = resultset.fields
    local rrows = resultset.rows

    local fields = {}
    local rows = {}
    local pos = 1

    -- Rows
    for row in rrows do
        rows[pos] = row
        pos = pos + 1
    end

    -- Fields
    pos = 1
    for i = 0, #rfields do
        if rfields[i] then
            fields[pos] = {
                type = rfields[i].type,
                name = rfields[i].name,
            }
        end

        pos = pos + 1
    end

    return Json.Encode({
        fields = fields,
        rows = rows,
    })
end

-- Callback called before request database server
function read_query(packet)
    if string.byte(packet) == proxy.COM_QUERY then
        local sql = string.sub(packet, 2)

        if string.match(string.lower(sql), '^%s*select') then
            -- Transform to valid key string
            local key = encode_key(sql)

            -- Gets from cache
            local rset = conn:get(key)

            -- If not found in cache, requests from database server
            if rset == nil then
                proxy.queries:append(1, packet)
                return proxy.PROXY_SEND_QUERY
            end

            -- Print out
            print('from cache', key)

            -- Json -> table
            rset = Json.Decode(rset)

            -- Todo: check for error returns
            proxy.response.type = proxy.MYSQLD_PACKET_OK
            proxy.response.resultset = rset

            return proxy.PROXY_SEND_RESULT
        end
    end
end

-- Callback called after request to database server
function read_query_result(inj)
    local res = resultset_to_str(inj.resultset)
    local sql = string.lower(string.sub(inj.query, 2))
    local key = encode_key(sql)
    local expire_time = default_expire_time

    -- Looks at patterns for respective expire time
    for i = 0, #patterns_expire_time do
        if patterns_expire_time[i] and string.match(sql, patterns_expire_time[i][1]) then
            expire_time = patterns_expire_time[i][2]
            break
        end
    end

    -- Saves to cache
    conn:set(key, res, expire_time)
end

Lá no início, as linhas que definem local conn e local patterns_expire_time devem ser ajustadas à sua realidade (endereço do servidor e patterns). Para saber como definir expressões regulares em Lua veja em [8] (é um pouquinho diferente do convencional).

Este script depende de dois pacotes externos à linguagem: json.lua [9] e Memcached.lua [10], que por sua vez depende do LuaSocket [11].

No Ubuntu, quando se instala o pacote mysql-proxy a lib da Lua 5.0 é instalada também, mas acontece que os pacotes que eu citei acima - especialmente o LuaSocket - não funcionam corretamente com a versão 5.0.

A solução foi instalar a versão 5.1 em paralelo (o LuaSocket possui um pacote no Ubuntu chamado liblua5.1-socket2) e eliminar a pasta antiga de bibliotecas da versão 5.0 (/usr/share/lua/50/), criando um symlink da versão 5.1 (/usr/share/lua/5.1/) com o mesmo nome.

Ainda foi necessário definir a seguinte variável de ambiente

export LUA_INIT=@/usr/share/lua/50/compat-5.1.lua

Por fim, para dar vida ao script, basta executar

mysql-proxy \
    --proxy-lua-script=cached_queries.lua \
    --proxy-backend-addresses=127.0.0.1:3306
http://marinho.webdoisonline.com/blog/p/tela_mysql_proxypng/?img=1

Ao executar este comando, será aberta a porta 4040 que deve ser setada na setting DATABASE_PORT. Caso queira saber como sobrepor a porta 3306, veja em [19].

Uma observação importante: o MySQL possui um bug [12] (ou sei lá o que é) que obriga conexões para "localhost" serem via porta 3306, isso vale tanto para o client quanto para o pacote MySQLdb do Python. Você faz uma conexão para a porta 1365465321 ou qualquer outra e ele aponta para 3306. Portanto, ao usar a porta 4040, mude a setting DATABASE_HOST para "127.0.0.1" caso esteja usando "localhost".

No script acima há ainda uma séria limitação quanto ao tamanho da SELECT. Caso ela tenha mais que 245 caracteres, você terá um erro de tamanho da chave no cache. A solução é converter a expressão SELECT com MD5, SHA ou outor algorítimo que crie uma string única em cima de uma SELECT complexa. Eu não consegui fazer isso ainda, mas recomendo expressamente que faça esse ajuste eu espere que eu o faça antes de colocar em um servidor de produção.

Para mais detalhes sobre MySQL Proxy, veja em [13], [14], [15] e [16]

Para mais detalhes sobre Lua, veja em [17] e [18].

É isso aí... artigo feito no fim da noite tem quer ser rápido assim. Dúvidas, é só falar :)

PS: apesar de serem muito úteis para quem usa Django, todas essas configurações são compatíveis com qualquer linguagem ou sistema operacional, e com versões igual ou acima de 5.1 do MySQL.

PS2: agradeço ao Javier Guerra e David Given pelos esclarecimentos sobre a arquitetura da Lua e ao Giuseppe Maxia pelo bom tutorial [19] que desenvolvou sobre MySQL Proxy

PS3: essa foi a primeira vez na vida que escrevi algo em Lua, por favor, sinta-se à vontade para apontar eventuais falhas

Atualização: removendo a variável de ambiente LUA_INIT, o mysql-proxy rodou normalmente sobre a versão 5.1.

Links relacionados

[1]http://dev.mysql.com/downloads/cluster/index.html
[2]http://forge.mysql.com/wiki/MySQL_Proxy
[3]http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-replication-connection.html
[4]http://softwaremaniacs.org/soft/mysql_cluster/en/
[5]http://blog.globoi.com/producao/2008/04/16/brasileiros-na-mysql-conference/
[6]http://www.howtoforge.org/mysql_master_master_replication
[7]http://marinho.webdoisonline.com/blog/p/metodo-cache-para-queryset_158/
[8]http://lua-users.org/wiki/PatternsTutorial
[9]http://www.chipmunkav.com/downloads/Json.lua
[10]http://luamemcached.luaforge.net/
[11]http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/
[12]https://bugs.launchpad.net/ubuntu/+source/mysql-dfsg-5.0/+bug/241802
[13]http://del.icio.us/marinho/mysql+escalabilidade
[14]http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy.html
[15]http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy-scripting.html
[16]http://classdump.org/articles/2008/02/14/mysql-proxy-enhancements
[17]http://www.lua.org/manual/5.1/pt/
[18]http://lua-users.org/wiki/TutorialDirectory
[19](1, 2) http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html

Leia essa entrada em seu contexto original »

Migrando do mod_python para o mod_wsgi

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Já faz alguns meses que eu queria fazer alguns testes com o mod_wsgi, a alternativa ao mod_python que vem sendo cada vez mais comentada e sugerida na comunidade Django.

Ontem eu aproveitei o dia tranquilo pra unir o útil ao agradável e colocar isso em prática.

O que é WSGI?

Vamos "começar do começo": WSGI é mais simples do que parece, trata-se de uma interface definida pela PEP 333 [1] para intermediar a comunicação entre servidores web e frameworks Python. Ela surgiu pela necessidade qualquer um de nós nota com um pouco tempo: Python tem quilos de frameworksmuitas delas excelentes, e às vezes o mod_python parece ser um ornitorrinco em um ninho de coelhos quando implantamos alguns sites. É esquisito.

/blog/p/diagrama_apache_wsgi_djangopng/?img=1

Mudando para o mod_wsgi

Para usar o WSGI puramente, é bastante simples, vamos fazer um pequeno script para ilustrar

def application(environ, start_response):
    status_code = '200 OK'
    headers = [('Content-Type', 'text/html')]

    start_response(status_code, headers)

    return ['So <b>testando</b>!']

from paste import httpserver
httpserver.serve(application, port='8000')

Ao executar este script minúsculo e carregar em seu navegador a URL "http://localhost:8000", será exibido "So testando". Simples não? Veja

$ python my_app.py
serving on http://127.0.0.1:8000
/blog/p/teste_wsgigif/?img=1

No Django, a coisa exige só um pouco mais de detalhes, mas nada complexo. Como já explanado há poucos dias pelo Eric, da Metaphormedia, em [2], é recomendável que se crie dentro de seu projeto uma pasta "apache" com um script dentro chamado "django.wsgi" - estes nomes são escolha sua, mas eles têm sido usados por mais de uma referência. Com o conteúdo abaixo (modificado segundo as suas necessidades)

#!/usr/bin/env python
import os, sys

sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)+'/../'))

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

E configure seu apache, removendo o código que implementa o mod_python e adicionando o seguinte

WSGIScriptAlias / /caminho/do/seu/projeto/apache/django.wsgi

Agora, para funcionar, é preciso que seu sistema operacional tenha o mod_wsgi instalado. No Ubuntu/Debian você instala com o seguinte comando

$ sudo apt-get install libapache2-mod-wsgi

Pronto, ao reiniciar o Apache, seu projeto estará lá, bonitão, rodando através do WSGI :)

Porque mod_wsgi?

Bom, essa deve ser a pergunta que você deve estar se fazendo. Se o mod_python sempre foi a alternativa recomendada e funciona bem, porque mudar para o mod_wsgi?

O mod_wsgi tem se comportado mais escalável que o mod_python. Por escalabilidade, entende-se a capacidade de um site de suportar o crescimento de uso sem perder a performance ou travar.

Ao ajustar um servidor para usar o mod_wsgi, pude notar essas diferenças. Elas não são tão grandes que se possa perceber com um simples teste com Apache Bench. É necessário forçar para notar a diferença, que tem sido até 10% superior.

Esse servidor que usei para fazer esses testes é uma VM (em Xen) com 512MB de RAM, rodando em um amd64, numa rede bastante estável, em Londres, enquanto que o Apache Bench foi executado em minha máquina.

Veja abaixo como os dois modos se comportaram:

Para compreender a legenda, o número após o "n" trata-se da quantidade de requisições enviadas e o número após o "c" trata-se da quantidade de requisições concorrentes, ou seja, "n1000c5" equivale a "1000 requisições enviadas de 5 em 5).

Tempo de resposta por requisição

/blog/p/tempo_de_resposta_por_requisicaopng/?img=1

Requisições por segundo

/blog/p/requisicoes_por_segundopng/?img=1

Load de 1 minuto

/blog/p/load_de_1_minutopng/?img=1

Load de 5 minutos

/blog/p/load_de_5_minutospng/?img=1

RSS / Memória real ocupada

/blog/p/rss_memoria_ocupadapng/?img=1

Percentual da CPU

/blog/p/percentual_da_cpupng/?img=1

Conclusões

Todos os números apresentados acima não podem ser tomados como base exata para comparação, por alguns motivos, como a influência que o teste anterior efetua no subsequente, a oscilação da internet e a influência de outros processos.

Eu fiz questão de usar um servidor em produção onde está sendo servido um outro sistema da empresa, que mesmo que não estivesse em seu horário de pico, era usado normalmente por alguns usuários.

Há ainda toda a questão de controvérsias em torno do uso real da CPU e da memória.

Mas dá pra notar uma realidade clara: o mod_swgi se mostra mais vantajoso em memória e tempo de resposta. Não esqueçamos que 200 requisições concorrentes para um VPS com 512MB de RAM é uma senhora carga, equivalente a alguns milhões de pageviews por mês.

No teste de 2000 requisições a 200 concorrentes, ficou visível que a configuração de MaxRequestsPerChild (de 1000) entrou em cena e fez diferença no desempenho, tanto para segurar a carga quando para mudar um pouco a evolução do desempenho.

Por fim, devo avisar que no teste seguinte, de 5000 requisições a 200 concorrentes, o Apache caiu antes de completar 3000, em 3 tentativas.

Mais detalhes sobre o WSGI podem ser encontrados em [4], [5] e [6]

Links relacionados

[1]http://www.python.org/dev/peps/pep-0333/
[2]http://www.ericholscher.com/blog/2008/jul/8/setting-django-and-mod_wsgi/
[3]http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
[4]http://www.slideshare.net/hdiogenes/wsgi-a-resposta-para-a-questo-definitiva-sobre-python-a-web-e-tudo-mais-368429?src=embed
[5]http://en.wikipedia.org/wiki/Wsgi
[6]http://www.wsgi.org/wsgi/
[7]http://del.icio.us/marinho/wsgi

Leia essa entrada em seu contexto original »

Entrevista com Jacob Kaplan-Moss

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Esse é um cara que eu admiro pela simplicidade e capacidade de liderança que demonstra a cada dia onde eu tenho a oportunidade de acompanhar.

Esta é a minha primeira entrevista e eu queria tirar minhas principais dúvidas envolvendo necessidades de grandes portais e sistemas corporativos, além de saber um pouco mais sobre as novidades mais quentes dos últimos mêses: Django Foundation, DjangoCon e versão 1.0.

Segue abaixo a gostosa conversa que tive com Jacob Kaplan-Moss, que poderia ter se extendido por mais um bom tempo, se não fosse a necessidade de parar por aí :)

Espero que gostem.

Marinho: bom, como eu disse, sou brasileiro, e o Brasil já tem muitos djangonautas, muita gente usando (o Django) para soluções corporativas e algumas grandes empresas começando a usá-lo em alguns projetos em fase inicial... a comunidade está crescendo e nós muito felizes :) então, minhas perguntas são relacionadas à nossa realidade.

e antes de tudo, eu gostaria de deixar você sabendo que meu inglês não é dos melhores, então, tenha paciência comigo :)

Jacob: Seu inglês está legal, não se preocupe!

É muito legal ouvir sobre o Django sendo usado ao redor do mundo; me faz realmente feliz.

Marinho: Eu noto :) você me respondeu com uma disponibilidade bacana, você parece ser um cara com boas habilidades em liderança. Ao longo da história do Django, você teve alguma situação nas relações pessoais que te desafiou?

Digo: uma situação quando você perdeu a paciência ou uma discussão ruim...

Jacob: Yeah, certamente aconteceu!

Marinho: as recentes surpresas (para nós) como a DjangoCon [5] e a Django Foundation [4] tiveram algum desses desafios?

Jacob: Nós tentamos realmente manter um tom amigável (ou ao menos educado), mas... às vezes há pessoas que são realmente difíceis de se lidar.

Marinho: Eu sei um pouco disso, e liderar uma grande comunidade não é uma tarefa fácil

Jacob: Há uma ótima palestra que Ben Collins-Sussman [1] e Brian Fitzpatrick [2] dão, chamada "How Open Source Projects Survive Poisonous People" ("Como Projetos de Código Aberto Sobrevivem a Pessoas Diabólicas") [3] cheio de bons conselhos -- as lições que eles dão têm salvado meu traseiro algumas vezes.

Marinho: legal, eu vou tirar um tempo pra assistí-lo...

agora sobre a Django Foundation [4]:

O que podemos esperar dela para os próximos anos? Que tipos de ações?

Jacob: Nós realmente não pensamos que haverá um grande avanço, honestamente. Nossa principal meta é ter um corpo "oficial" que pode representar o Django e ajudar financeiramente. Como a maioria das coisas em torno do Django, nós vamos esperar para ver o que a comunidade quer que façamos.

A grosso modo, nós vamos bancar os sprints de desenvolvedores e reuniões para ajudar o Django 1.0 a sair no tempo (certo).

Marinho: Podemos esperar por uma certificação ou algo semelhante?

Jacob: Você quer dizer algum tipo de "certificação para desenvolvedor" oficial do Django?

Marinho: sim

Jacob: Nós não temos planos para isso por agora... não parece ser algo que nós queremos nos envolver, mas como eu disse antes, se isso for algo que a comunidade realmente quer, é claro que vamos tentar ajudar.

Marinho: A comunidade de Python não gosta de certificações, mas muitas empresas gostam... é algo que as faz se sentir mais seguras

Jacob: Yeah, eu entendo... é só algo que não é muito comum no Open Source em geral; não estou certo de como isso funciona.

Marinho: sim, eu concordo.

e sobre a DjangoCon [5], que mais detalhes podemos ter a respeito? Vocês já tem alguma data?

Jacob: Nós estamos só finalizando alguns detalhes, e devo estar pronto pra anunciá-los talvez hoje, talvez na segunda.

Marinho: ótimo :)

agora sobre o ORM e novas funções...

Você tem alguma idéia de quando poderemos ter suporte a SGBDOO (bancos de dados orientados a objetos), especialmente BigTable, Amazon SimpleDB e ZoDB? Quão difícil isso seria pra fazer?

Jacob: Isso realmente é algo que eu venho pensando muito ultimamente -- repentinamente há todo um punhado desses bancos de dados não-relacionais saindo, seria fascinante suportá-los.

Eu penso realmente que nem tudo seria aquela dificuldade, no entanto você deve se lembrar que nenhum desses DBs realmente suportam joins ou outras características relacionais, então você nunca poderia mesmo só mudar o DATABASE_ENGINE da mesma forma e esperar que sua aplicação funcione.

Marinho: sim, isso é o que eu estava pensando...

E sobre suporte (aos recursos de) master/slave [6] do MySQL e conexões com múltiplos bancos de dados?

Jacob: Eu não sou de todo familiar com o MySQL, então eu provavelmente sou a pessoa errada a se perguntar sobre ele. Para múltiplas conexões, há um bom trabalho sendo feito na área; ele não estará na (versão) 1.0 por causa do tempo, mas estou esperançoso de que nós teremos em breve.

Marinho: Entendi... essa (minha) pergunta é porque a maioria dos grandes sites, como o Flickr, YouTube, Slashdot e outros costumam adotar o armazenamento de dados em muitos (e às vezes aleatórios) servidores de banco de dados.

Agora sobre o uso do Django e o futuro...

Um ou dois anos atrás, você pensava sobre o Django sendo usado como framework para se criar softwares corporativos como ERPs, BIs, CRMs, Billing (Vendas) e outros softwares para uso em empresas, especialmente não relacionados ao gerenciamento de conteúdo?

Jacob: Quando nós lançamentos a primeira release do Django, nós nunca esperávamos que ela seria largamente usado como é (hoje). Nós pensamos que talvez alguns outros publicadores online se interessariam, e talvez nós pegássemos alguma relevância na comunidade (que usa) Python na web. Nós nunca pensamos que o Django seria usado em muitos lugares (redes sociais, software corporativo/empresarial, vendas online...)

Marinho: e agora como você sente quando vê que dia-após-dia mais pessoas usam-no em tipos totalmente diferentes de soluções? Surpreso? :)

Jacob: Surpreso, sim, mas principalmente feliz. É realmente ótimo, e todos os diferentes usos confirmam que o Django realmente funciona bem.

Isto é, tendo todas essas pessoas com diferentes necessidades confirmando que nós não nos prendemos a um nicho em particular.

Marinho: sim, é verdade... Eu acho que você se sente orgulhoso quando sabe que grandes players como Google e Yandex [7] estão usando-o :)

Jacob: Exatamente -- é realmente bacana.

Marinho: O que você considera que serão os grandes desafios para o framework nos próximos anos?

Jacob: Eu acho que nosso grande desafio é lidar com nosso próprio sucesso. Nós aguardamos muito tempo para soltar a 1.0, principalmente porque nós não compreendemos quão grandes nós ficamos -- com uma pequena comunidade, você pode arriscar a se sujar. Agora que nós somos realmente um projeto de grandes proporções, nós precisamos formalizar mais o nosso fluxo de trabalho: versões planejadas e regulares, divisão mais explícita e delegação de responsabilidades, etc.

Nós também precisamos estar dispostos para uma inevitável oposição quando ela vier. Como um grande projeto você inevitavelmente terá eventualmente pessoas que simplismente te odeiam, e lidar com o lado baixo do sucesso pode ser desagradável. Eu tenho acompanhado com cuidado como a comunidade de Rails segurou a carga de "Rails não escala!" e "Rails não é seguro!" neste último ano; eles realmente fizeram um grande trabalho ouvindo as vozes racionais e ignorando as pessoas que estavam só para contrariar.

Nós vamos certamente ter "controvérsias" como essas no futuro; nós precisamos de ter certeza que nós podemos segurar isso profissionalmente.

Marinho: Eu entendo, agora o Django vive uma nova realidade, diferente de antes

Jacob: Exatamente. Nós temos que prestar atenção em como nossa comunidade se desenvolve e aceita nossa liderança ao seu encontro.

Marinho: sim, é verdade... bom, indo para o fim: o que mais você pode nos dizer? Algo quente? Alguma novidade que não sabemos?

Jacob: Hmm... nós fazemos a maioria das coisas publicamente -- a fundação e a conferência são realmente as únicas duas exceções -- então eu não acho que há algo "em segredo" por agora. A próxima grande coisa para nós é o Django 1.0 Alpha que está saindo em uma semana -- que será um grande marco, e nós precisaremos de grande ajuda para testá-la até que a (versão) 1.0 final esteja melhor possível.

Marinho: o.O ótimo, essa é uma grande novidade para a comunidade :)

bom, eu agradeço por tudo, lhe parabenizo pelo sucesso e pela boa conversa, eu sou um orgulhoso e grato djangonauta e quero ajudar sempre que puder.

Jacob: Obrigado

Links relacionados

[1]http://www.red-bean.com/sussman/
[2]http://www.red-bean.com/fitz/
[3]http://vivixvideo.com/videos/ource-projects-survive-poisonous-people-and-you-can-too/
[4](1, 2) http://www.djangoproject.com/foundation/
[5](1, 2) http://www.ericholscher.com/blog/2008/jul/7/djangocon-2008/
[6]http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-replication-connection.html
[7]http://kuda.yandex.ru/

Leia essa entrada em seu contexto original »

Interview with Jacob Kaplan-Moss

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Marinho: well, as I said, I'm brazilian, and Brazil has already many djangonauts many people using for corporate solutions and some big companies starting to use in some startup projects... the community is growing and we very happy :) so, my questions are related to our reality and first at all, I wish to let you know that my english is not the best, so, be patient with me :)

Jacob: Your English is fine, no worries! It's so cool hearing about Django getting used around the world; makes me really happy.

Marinho: I see :) you replied to me with a nice availability, you seem to be a guy with good skills of leadership. Along the Django's lifetime, did you have some situation about people relations that dare you? I mean: some situation when you lost the patience or bad discussion...

Jacob: Yeah, it's certainly happened!

Marinho: the recent suprises (for us) like DjangoCon and Django Foundation was some of those dares?

Jacob: We try really hard to maintain a friendly (or at least polite) tone, but... sometimes there are people who are just really difficult to deal with.

Marinho: I know a bit of this, and leading a great community is not an easy job

Jacob: There's a great talk that Ben Collins-Sussman and Brian Fitzpatrick give called "How Open Source Projects Survive Poisonous People": http://video.google.com/videoplay?docid=-4216011961522818645 Full of good advice -- the lessons they give there have saved by butt a few times.

Marinho: cool, I will spare some time to watch it about the Django Foundation: What can we wait from it for the next years? What kind of acts?

Jacob: We haven't really thought all that far in advance, honestly. Our main goal is to have an "official" body that can represent Django and help out financially. Like most things around Django, we'll wait to see what the community wants us to do. In the short term, we'll be sponsoring developer sprints and meetups to help get Django 1.0 out on time.

Marinho: Can we wait for certification or something like this?

Jacob: Do you mean some sort of official Django "developer certification"?

Marinho: yep

Jacob: We don't have any plans for that right now... it doesn't seem like something we'd want to get involved in, but as I said before if it's something the community really wants, we'd of course try to help out.

Marinho: Python community doesn't like certifications, but many companies like... is something that they feels more safe understood

Jacob: Yeah, I understand... it's just something that's not very common in Open Source in general; not sure how it'd work.

Marinho: yes, I agree and about the DjangoCon, what more details can we have about? have you already the date?

Jacob: We're just finalizing some details, and should be able to announce them maybe today, maybe Monday.

Marinho: great :) about the ORM and new features... Have you some idea about when could we have support to OODBMS, especially BigTable, Amazon SimpleDB and ZoDB? How much hard could this to do?

Jacob: This is actually something I've been thinking a lot about lately -- there's all of a sudden a bunch of these non-relational databases coming out, it would be awesome to support them. I think it's actually not all that hard, though you have to remember that none of these DBs really support joins or other relational features so you could never really just switch DATABASE_ENGINE on the fly and expect your app to work.

Marinho: yes, this is what I was thinking about And about MySQL master/slave support and multiple database connections?

Jacob: I'm not all that familiar with MySQL, so I'm probably the wrong person to ask there. As for multiple connections, there's some good work being done in that area; it won't make it into 1.0 because of timing, but hopefully we'll get it in soon.

Marinho: I see... this question is because most of great sites, like Flickr, YouTube, Slashdot and others use to adopt storing data in many (and sometimes randomic) database servers Now about the Django usage and the future...

One or two years ago, thought you about Django being used as framework to create corporate softwares like ERPs, BIs, CRMs, Billing and other software for use in companies, especially not related to content management?

Jacob: When we first released Django, we never expected it to be as widely-used as it is. We though that maybe a few other online publishers would be interested, and perhaps we'd get some traction within the Python web community. We never thought that Django would get used in so many places (social networking, corporate/enterprise software, online shopping...)

Marinho: and now how do you feel when see that day-by-day more people use it in totally different kinds of solutions? Surprised? :)

Jacob: Surprised, yeah, but mostly just happy. It's really great, and all the disparate uses ensure that Django really works well. That is, having all these people with different needs ensures that we don't get stuck in some particular niche.

Marinho: yes, is true... I think you feel so proud when knows that great players like Google and Yandex are using it :)

Jacob: Exactly -- it's really nice.

Marinho: What do you consider will be the great challenges for the framework in the next years?

Jacob: I think our greatest challenge is dealing with our own success. We delayed far to long getting 1.0 out, mostly because we didn't realize quite how large we'd gotten -- with a small community, you can afford to be a lot more sloppy. Now that we're really a big-time project we need to formalize our workflow more: regular, scheduled releases, more explicit division and delegation of duties, etc. We also need to be ready for the inevitable backlash when it comes. As a large project you're inevitably going to eventually have people who just hate you, and dealing with the downside of success can be nasty. I've watched carefully how the Rails community handled the "Rails doesn't scale!" and "Rails is insecure!" stuff over the last year; they really did a great job listening to the rational voices and ignoring the people there just for kicks. We'll certainly have "controversies" like that in the future; we need to make sure we handle them professionally.

Marinho: I understand, now Django lives a new reallity, diferent than before

Jacob: Exactly. We have to pay attention to how our community evolves and evolve our leadership to meet them.

Marinho: yes, is a truth... well, now going to the end: what more could you say to us? Something hot? Some newness that we don't know? :)

Jacob: Hmm... we do most things out in public -- the foundation and the conference are really the only two exceptions -- so I don't think there's anything left that's "secret" now. The next big thing for us is that Django 1.0 Alpha will be coming out in just over a week -- that'll be a great milestone, and we'll need lots of help testing it so that the final 1.0 release can be as good as possible.

Marinho: o.O great, this is a great newness for the community :) well, I thank you for all, and congratule you for the success and for this nice talk, I'm a proud and thankful djangonaut and want to help ever I can

Jacob: Thank you! Let me know when you post this; I'd love to read it.

Marinho: I will publish this maybe monday or tuesday in my blog or in the DjangoBrasil blog, I'm not sure about this, but I will try to publish early I can :) yes, I will have a good afternoon

Jacob: Thanks; you too.

Leia essa entrada em seu contexto original »

Método .cache() para QuerySet

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Resolvi publicar este como um artigo separado. Por ser maior e mais importante.

No momento trata-se apenas de um patch em avaliação pelo core team. Se for adotada pelo framework, dificilmente será na versão 1.0, prevista para setembro [1].

A criação desse método, que depende de ajuste direto no código-fonte do framework, surgiu da necessidade de criar uma solução escalável para requisições redundantes ao banco de dados, especialmente as concorrentes.

Em resumo, quando utilizado encadeado a uma chamada de QuerySet [2], o método armazena o resultado do banco em cache e na próxima vez que aquela requisição for feita, ela será feita ao cache antes de chegar até o banco. O ganho de performance é notável, mas a escalabilidade ficou tremenda. O cache backend deve ser de preferência de memória, como o memcached [3] ou locmem [4]).

Seu uso pode ser bastante amplo e deve-se tomar o cuidado de respeitar o timeout e de usá-lo somente em requisições onde se tem uma visão clara quanto a essa chamada depender de atualizações constantes no banco de dados. Minha intuição é de que 90% das requisições não terão alterações relevantes em menos de 60 segundos, mas isso vai varia de acordo com a realidade do site ou sistema.

Usos mais prováveis do método:

Dentro de uma QuerySet declarada

class CategoriaManager(models.Manager):
    def get_query_set(self):
        q = super(CategoriaManager, self).get_query_set()

        return q.cache(300)

Observe que este código faz com que TODAS as requisições a banco feitos através deste manager sejam feitas através do recurso de cache. Isso é perigoso, viu?

Encadeado a uma QuerySet individual

lista = Video.all().cache(300)

Note que agora o uso do cache se limitou a uma chamada, um tanto genérica.

Moral da história: se você tem 1 usuário requisitando uma lista de Video, ela será armazenada por 300 segundos. Digamos que nesses próximos 300 segundos você tenha 100 requisições idênticas ao banco de dados (mesmo que partam de partes diferentes do código), todas essas requisições serão alimentadas pelo cache (e você sabe: memória é mais veloz que disco rígido). Quanto mais requisições simultâneas, mais robusto o sistema fica. Isso se chama escalabilidade. E claro, performance.

A idéia ficou tão legal, que já está fazendo influência, como o snippet [6].

Mais detalhes em [5]

Links relacionados

[1]http://code.djangoproject.com/wiki/VersionOneRoadmap
[2]http://www.djangoproject.com/documentation/db-api/#queryset-methods-that-return-new-querysets
[3]http://www.djangoproject.com/documentation/cache/#memcached
[4]http://www.djangoproject.com/documentation/cache/#local-memory-caching
[5]http://code.djangoproject.com/ticket/7338
[6]http://www.djangosnippets.org/snippets/815/

Leia essa entrada em seu contexto original »

Aplicações plugáveis django-antivirus e django-ads, e outras coisas

Publicado em 24/07/2008 às 19h00
Marinho Brandão feed

Dois meses.

É tempo demais para ficar sem publicar nenhum artigo sequer.

Mas foi um tempo que passou rápido demais, eu francamente não havia percebido que se foram 2 meses desde o último artigo.

Fazendo um resumo geral desse tempo, basicamente trabalhei em minhas tarefas diárias na WorldNews [1] e no VivixVideo [2], tive muitas horas divertidas com a Tarsila [3] e alguma dedicação em projetos livres (mais detalhes mais adiante). Também estive mais envolvido que o normal no mercado financeiro, agora operando como day trader, e você sabe: vivemos dias atribulados na bolsa, então toda a atenção é necessária.

Mas enfim, quero mesmo é falar sobre o que trabalhei nas últimas semanas que está disponível para desenvolvedores Python que utilizam Django.

django-dynamic

Ainda engatinhando. É um projeto que visa no longo prazo oferecer uma alternativa amigável para publicação e manutenção de sites em Django. Já conta com gerenciador de configurações diversas para o site (entre elas o recurso de colocar o site em manutenção através do Admin).

Conta também com um SQL Shell e um File Manager, respectivamente para gerenciar o banco de dados e os arquivos do site.

Veja mais detalhes em [4]

django-antivirus

Projeto que fiz ontem.

Trata-se da integração do Django com antivirus. Neste momento somente o ClamAV é suportado. Em resumo a aplicação oferece uma classe de modelo para se registrar arquivos e solicitar sua verificação por virus.

Isso pode ser feito facilmente por um template filter, que se resume a informar o objeto e o nome do campo onde está informado o arquivo. O retorno desse filtro é uma requisição Ajax que verifica o arquivo por virus e exibe um link para download. Caso um virus seja encontrado, é exibida uma mensagem com essa informação e o arquivo é verificado somente uma vez, portanto, na próxima vez que alguém requisita aquela página ela exibe a informação armazenada.

Mais detalhes em [5]

django-ads

Aplicação que levou uns 10 dias de trabalho. Em poucas palavras, faz o que o Google AdWords faz - guardadas as devidas proporções. Também tem um recurso interessante para a publicação rotativa ou baseada em regras para banners, propagandas e outros programas de afiliados. Simples de usar e bastante poderoso.

Mais detalhes em [6]

SectionedForm

Não sei se o nome ficou bom, mas o código me ajudou bastante.

Sabemos que o Admin permite se dividir o form em seções, através dos fieldsets. Mas isso não é suportado pelo NewForms.

Pois bem, esse snippet é pra isso. Você herda seu form do SectionedForm and declara os atributos:

sections = (
    (None, ('name','age','date')),
    (_('Last Employment'), ('name','date','position','location_country','location_city')),
)

Ele irá criar um subtitulo "Last Employment" e colocar os campos listados abaixo ;)

Mais detalhes em [7]

Bom, é isso aí. Outros snippets interessante que fiz podem ser encontrados em [8]. No mais agora é aguardar ansiosamente pela PyCon Rio [9] e pela versão 1.0.

Links relacionados

[1]http://wn.com/
[2]http://vivixvideo.com/
[3]http://www.flickr.com/photos/marinho/1173837495/in/set-72157594192378034/
[4]http://code.google.com/p/django-dynamic/
[5]http://code.google.com/p/django-antivirus/
[6]http://code.google.com/p/django-ads/
[7]http://www.djangosnippets.org/snippets/798/
[8]http://www.djangosnippets.org/users/marinho/
[9]http://pyconbrasil.com.br/

Leia essa entrada em seu contexto original »


Hospedado por PyTown.com. Django Brasil é a comunidade brasileira de usuários do framework web Django. Django é uma marca registrada de Lawrence Journal-World.