Python 在syncdb期间阻止代码运行

Python 在syncdb期间阻止代码运行,python,django,django-models,django-syncdb,syncdb,Python,Django,Django Models,Django Syncdb,Syncdb,我有一些代码抛出导致syncdb抛出错误,因为它试图在创建表之前访问模型 有没有办法阻止代码在syncdb上运行?比如: if not syncdb: run_some_code() 谢谢: 编辑:PS-我考虑过使用post_init信号。。。对于访问数据库的代码,这是个好主意吗 更多信息 以下是所需的更多信息: 例如,我已经遇到过几次了。。。我正在攻击django cron,并确定在加载django时必须确保没有现有作业,因为它会搜索所有已安装的应用程序中的作业,并在加载时添加它们

我有一些代码抛出导致syncdb抛出错误,因为它试图在创建表之前访问模型

有没有办法阻止代码在syncdb上运行?比如:

if not syncdb:
    run_some_code()
谢谢:


编辑:PS-我考虑过使用post_init信号。。。对于访问数据库的代码,这是个好主意吗

更多信息 以下是所需的更多信息:

例如,我已经遇到过几次了。。。我正在攻击django cron,并确定在加载django时必须确保没有现有作业,因为它会搜索所有已安装的应用程序中的作业,并在加载时添加它们

因此,我在_init__.py文件的顶部添加了以下代码:

显然,这是废话。它与sqlite相关联,我相信有更好的地方可以放这段代码。这就是我在这个问题上遇到的情况,但它是有效的

正如您所看到的,您得到的错误是sqlite中的操作错误,堆栈跟踪显示了与表django_cron_job not found类似的内容

解决方案 最后,目标是在加载任何页面之前运行一些代码

这可以通过在URL.py文件中执行它来实现,因为必须先导入它,然后才能提供页面


我能够删除那个丑陋的try/except块:谢天谢地和S.Lott

在创建模型之前试图访问模型的代码几乎只能存在于模块级;正如您的示例所示,它必须是在导入模块时运行的可执行代码。正如您所猜测的,这就是syncdb失败的原因。它尝试导入模块,但导入模块的行为会导致执行应用程序级代码;副作用,如果你愿意的话

Python中强烈希望避免导致副作用的模块导入,因此可执行Python脚本的if _uname _u=='_umain_uuu':约定已变得司空见惯。当仅加载代码库导致应用程序开始执行时,会出现以下问题:-

对于Django应用程序来说,这不仅仅是一个头痛的问题。考虑在每次导入模块时执行OLDJOBE的效果。在使用Django开发服务器运行时,它似乎只执行一次,但在生产环境中,它会经常执行。例如,如果您使用Apache,Apache将经常启动几个等待处理请求的子进程。随着长时间运行的服务器的发展,每次为您的web服务器派生处理程序时,您的Django应用程序都将启动,这意味着模块将被导入,并且删除将被多次调用,这通常是不可预测的。不幸的是,信号没有帮助,因为每次初始化Apache进程时都会触发信号

顺便说一句,它不仅仅是一个可能导致代码意外执行的Web服务器。例如,如果您使用像epydoc这样的工具,他们将导入您的代码以生成API文档。这反过来会导致应用程序逻辑开始执行,这显然是仅仅运行文档解析器的一个不希望的副作用

因此,像这样的清理代码最好由cron作业来处理,它会定期查找过时的作业并清理数据库。此自定义脚本也可以手动运行,也可以在部署期间由任何进程运行,或者作为单元测试设置功能的一部分运行,以确保干净的测试运行。无论您如何执行,重要的一点是,像这样的代码应该始终显式执行,而不是作为打开源文件的结果隐式执行


我希望这有帮助。我知道它无法确定syncdb是否正在运行,但如果您在设计Django应用时考虑到生产部署,syncdb问题将神奇地消失。

在创建模型之前尝试访问模型的代码几乎只能存在于模块级别;正如您的示例所示,它必须是在导入模块时运行的可执行代码。正如您所猜测的,这就是syncdb失败的原因。它尝试导入模块,但导入模块的行为会导致执行应用程序级代码;副作用,如果你愿意的话

Python中强烈希望避免导致副作用的模块导入,因此可执行Python脚本的if _uname _u=='_umain_uuu':约定已变得司空见惯。当仅加载代码库导致应用程序开始执行时,会出现以下问题:-

对于Django应用程序来说,这不仅仅是一个头痛的问题。考虑在每次导入模块时执行OLDJOBE的效果。在使用Django开发服务器运行时,它似乎只执行一次,但在生产环境中,它会经常执行。例如,如果您使用Apache,Apache将经常启动几个等待处理的子进程 e请求。随着长时间运行的服务器的发展,每次为您的web服务器派生处理程序时,您的Django应用程序都将启动,这意味着模块将被导入,并且删除将被多次调用,这通常是不可预测的。不幸的是,信号没有帮助,因为每次初始化Apache进程时都会触发信号

顺便说一句,它不仅仅是一个可能导致代码意外执行的Web服务器。例如,如果您使用像epydoc这样的工具,他们将导入您的代码以生成API文档。这反过来会导致应用程序逻辑开始执行,这显然是仅仅运行文档解析器的一个不希望的副作用

因此,像这样的清理代码最好由cron作业来处理,它会定期查找过时的作业并清理数据库。此自定义脚本也可以手动运行,也可以在部署期间由任何进程运行,或者作为单元测试设置功能的一部分运行,以确保干净的测试运行。无论您如何执行,重要的一点是,像这样的代码应该始终显式执行,而不是作为打开源文件的结果隐式执行


我希望这有帮助。我知道它无法确定syncdb是否正在运行,但如果您在设计Django应用程序时考虑到生产部署,syncdb问题将神奇地消失。

编辑:PS-我考虑过使用post_init信号。。。对于访问数据库的代码,这是个好主意吗

从来没有

如果您的代码在创建表之前访问模型,那么您会遇到非常大的问题。你可能做错了什么

通常,您大约运行一次syncdb。数据库已创建。您的web应用程序使用数据库

有时,您会更改设计,删除并重新创建数据库。然后您的web应用程序会长时间使用该数据库

通常,您不需要在_uinit__uu.py模块中使用代码。您几乎不应该有在_init__u; py.py模块中执行实际工作的可执行代码。这是非常非常罕见的,不适合Django

我不知道你为什么要在URL.py中做日程安排的时候,搞砸了

编辑

清理记录是一回事

使用uuu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果事情那么复杂,你就做错了

不可能知道你想做什么,但这应该是微不足道的

您的urls.py只能在syncdb和所有ORM资料正确配置和绑定后运行

例如,您的urls.py可以删除一些行,然后向表中添加一些行。此时,所有syncdb问题都已解决


为什么不把逻辑放在url.py中?

编辑:PS-我考虑过使用post\u init信号。。。对于访问数据库的代码,这是个好主意吗

从来没有

如果您的代码在创建表之前访问模型,那么您会遇到非常大的问题。你可能做错了什么

通常,您大约运行一次syncdb。数据库已创建。您的web应用程序使用数据库

有时,您会更改设计,删除并重新创建数据库。然后您的web应用程序会长时间使用该数据库

通常,您不需要在_uinit__uu.py模块中使用代码。您几乎不应该有在_init__u; py.py模块中执行实际工作的可执行代码。这是非常非常罕见的,不适合Django

我不知道你为什么要在URL.py中做日程安排的时候,搞砸了

编辑

清理记录是一回事

使用uuu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果事情那么复杂,你就做错了

不可能知道你想做什么,但这应该是微不足道的

您的urls.py只能在syncdb和所有ORM资料正确配置和绑定后运行

例如,您的urls.py可以删除一些行,然后向表中添加一些行。此时,所有syncdb问题都已解决


为什么不把逻辑放在url.py中?

我对涉及的代码和/或模型很好奇。我从来没有遇到过这个。。。事实上,我甚至不知道这是可能的,所以如果能看到代码和错误stacktrace,我将不胜感激。@Jim Robert:你的试探性回答听起来像是一个新的、不相关的问题。此问题的标题与暂定答案的主题不匹配。您可能希望删除此部分,并就此主题提出一个新问题。@S.Lott感谢您的帮助:删除该部分我对涉及的代码和/或模型非常好奇。我从来没有遇到过这个。。。事实上,我甚至不知道这是
可能,所以我很高兴看到代码和错误。@Jim Robert:你的初步回答听起来像是一个新的、不相关的问题。此问题的标题与暂定答案的主题不匹配。您可能想删除此内容,并就此主题提出一个新问题。@S.Lott感谢您的帮助:将该部分去掉关于post_init信号,我意识到它没有像我所想的那样工作,因此这种方法不起作用。上面的代码片段被移到django cron中的base.py文件中,但随着应用程序的设计,我认为在应用程序启动时仍有必要清除数据库中的所有记录,因为一旦你杀死django或重启服务器,它就不记得作业了。关于post_init信号,我意识到它没有做我认为它做的事情,因此,这种方法不起作用上面的代码片段被移动到django cron中的base.py文件中,但随着应用程序的设计,我认为在应用程序启动时仍有必要清除数据库中的所有记录,因为一旦您杀死django或重新启动服务器,它就不记得作业了耶。。。我只是想找出足够的方法让这个应用程序运行起来,我没有写它,但也许我会投入时间重构它,直到事情变得有意义:是的。。。我只是想找出足够的方法让这个应用程序运行起来,我没有编写它,但也许我会投入时间重构它,直到事情变得有意义为止:
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