8 de novembro de 2010

request.now ou datetime.now?

O Web2py tem a variável request.now que você pode usar no lugar de datetime.datetime.now() sem precisar importar nada. Essa variável guarda o horário que a requisição foi executada.

Eu estou fazendo uma aplicação com uma parte rodando via cron e me deparei com uma situação inusitada: todos os registros alterados no processo da cron tinham o mesmo horário de modificação. Isso porque eu usei o update=request.now na definição do campo que guarda a hora da última modificação do registro.

A situação é que, no shell (cron), a requisição ocorre apenas uma vez, no momento que ele é iniciado. Já na web, a requisição ocorre toda vez que uma URL é solicitada pelo browser. Como no shell a característica é executar processos em background, não existe a URL sendo solicitada. Na web, a cada clique de link ou de botão, uma nova requisição é realizada.

Então, o request.now, na verdade, contém o horário que a requisição iniciou.

Para resolver meu problema, eu passei a usar o update=datetime.datetime.now(). Conferindo os resultados depois dessa modificação, me deparei com o mesmo problema: todos os registros alterados pelo processo da cron com o mesmo horário de modificação.

Recorri à lista mundial do web2py e aprendi que esses valores para default e update são avaliados apenas no momento que os models são executados, quando associados a conteúdos fixos ou variáveis.

Para resolver o problema, temos que usar lambda assim: update=lambda:datetime.datetime.now(). Dessa forma, como temos a chamada de uma função (lambda no nosso caso), toda vez que um registro for modificado, esse conteúdo do update será reavaliado.

O mesmo vale para a propriedade default.

Portanto, use os parâmetros default e update com lambda, para que atualizem o conteúdo no momento de inserção/alteração do registro.

Segue um exemplo:

from datetime import datetime
db.define_table('ficha',
    Field('nome', 'string'),
    Field('quando', 'datetime', default=lambda:datetime.now())

Nenhum comentário:

Postar um comentário