Pergunta

Eu tenho algum código que lança causas syncdb para lançar um erro (porque ele tenta acessar o modelo antes das tabelas são criadas).

Existe uma maneira de manter o código seja executado em syncdb? algo como:

if not syncdb:
    run_some_code()

Obrigado:)

Editar : PS - Pensei em usar o sinal post_init ... para o código que acessa o banco de dados, é que uma boa idéia

Mais informações

Aqui está mais algumas informações, conforme solicitado:)

Eu executar para esse algumas vezes, por exemplo ... Eu estava cortando em django-cron e determinou que é necessário para fazer trabalhos de certeza que não são existentes quando você carrega Django (porque ele procura todos os aplicativos instalados para empregos e adiciona-los na carga de qualquer maneira).

Então eu adicionei o seguinte código no início do arquivo __init__.py:

import sqlite3

try:
        # Delete all the old jobs from the database so they don't interfere with this instance of django
        oldJobs = models.Job.objects.all()
        for oldJob in oldJobs:
                oldJob.delete()
except sqlite3.OperationalError:
        # When you do syncdb for the first time, the table isn't 
        # there yet and throws a nasty error... until now
        pass

Por razões óbvias esta é uma porcaria. ele está vinculado ao sqlite e estou há melhores lugares para colocar este código (isto é apenas como me deparei com a questão), mas ele funciona.

Como você pode ver o erro que você recebe é erro operacional (em SQLite) e o rastreamento de pilha diz algo ao longo das linhas de "django_cron_job tabela não encontrado"

Solução

No final, o objetivo era executar algum código antes de quaisquer páginas foram carregadas .

Isso pode ser feito através da execução-lo no arquivo urls.py, uma vez que tem de ser importados antes de uma página pode ser servido (obviamente).

E eu era capaz de remover essa tentativa feio / except deus bloco :) Obrigado (e S. Lott)

Foi útil?

Solução

"edit:? PS - Pensei em usar o sinal post_init ... para o código que acessa o banco de dados, é que uma boa idéia"

Nunca.

Se você tem o código que está acessando o modelo antes das tabelas são criadas, você tem grandes, grandes problemas. Você provavelmente está fazendo algo seriamente errado.

Normalmente, você corre SyncDB aproximadamente uma vez. O banco de dados é criado. E sua aplicação web usa o banco de dados.

Às vezes, você fez uma alteração design, eliminar e recriar o banco de dados. E então seus usos de aplicações web que banco de dados por um longo tempo.

Você (geralmente) não precisa de código em um módulo __init__.py. Você deve (quase) nunca tem código executável que faz o trabalho real em um módulo __init__.py. É muito, muito raro, e impróprio para Django.

Eu não sei por que você está mexendo com __init__.py quando Django Cron diz que você fazer o seu regime de agendamento em urls.py.


Editar

registros de compensação é uma coisa.

Brincando com __init__.py e base.py do Django-cron são claramente completamente errado maneiras de fazer isso. Se é assim tão complicado, você está fazendo errado.

É impossível dizer o que você está tentando fazer, mas deve ser trivial.

Seu urls.py só pode ser executado após syncdb e depois de todo o material ORM foi configurado e ligado corretamente.

Seu urls.py poderia, por exemplo, excluir algumas linhas e, em seguida, adicionar algumas linhas a uma tabela. Neste ponto, todas as questões SyncDB estão fora do caminho.

Por que você não tem a sua lógica em urls.py?

Outras dicas

O código que tenta acessar a modelos antes de serem criadas pode muito bem existir apenas no nível do módulo; ele teria que ser executado código executável quando o módulo é importado, como o seu exemplo indica. Isto é, como você adivinhou, o motivo pelo syncdb falhar. Tenta para importar o módulo, mas o acto de importação do módulo faz com código de nível de aplicação para executar; um "efeito colateral" se você quiser.

O desejo de importações módulo evitar que causam efeitos colaterais é tão forte em Python que a convenção if __name__ == '__main__': para scripts Python executáveis ??tem se tornado comum. Quando apenas carregar uma biblioteca de código faz com que uma aplicação para iniciar a execução, dores de cabeça se seguem: -)

Para aplicativos Django, isso se torna mais do que uma dor de cabeça. Considere o efeito de ter oldJob.delete() executada toda vez que o módulo é importado. Pode parecer que ele está executando apenas uma vez quando você executa com o servidor de desenvolvimento do Django, mas em um ambiente de produção que serão executados com bastante frequência. Se você usar Apache, por exemplo, o Apache irá freqüentemente fogo até vários processos filhos esperando para pedidos punho. Como uma longa execução avanços servidor, seu aplicativo Django vai ficar bootstrapped cada vez que um manipulador é bifurcada para o seu servidor web, o que significa que o módulo será importado e delete() será chamado várias vezes, muitas vezes de forma imprevisível. Um sinal não vai ajudar, infelizmente, como o sinal poderia ser acionado toda vez que um processo Apache é inicializado também.

Não é, aliás, apenas um servidor que poderia causar seu código para executar inadvertidamente. Se você usar ferramentas como epydoc, por exemplo, eles irá importar o código para gerar documentação de API. Este, por sua vez causaria a lógica do aplicativo para iniciar a execução, o que é, obviamente, um efeito colateral indesejado de apenas correr um analisador documentação.

Por este motivo, o código de limpeza como este é ou melhor tratado por um trabalho cron, que procura empregos obsoletos em uma base periódica e limpa o DB. Este script personalizado também pode ser executado manualmente ou por qualquer processo (por exemplo, durante a implantação, ou como parte de sua função de teste setUp() unidade para garantir um teste limpo). Não importa como você fazê-lo, o ponto importante é que um código como este deve ser sempre executada explicitamente , em vez de implicitamente como resultado de abrir o arquivo de origem.

Espero que ajude. Eu sei que não fornece uma maneira de determinar se syncdb está funcionando, mas a questão syncdb magicamente irá desaparecer se você projetar seu aplicativo Django com implantação de produção em mente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top