我有一些代码会引发syncdb 引发错误(因为它尝试在创建表之前访问模型)。

有没有办法阻止代码在syncdb上运行?就像是:

if not syncdb:
    run_some_code()

谢谢 :)

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

更多信息

这是根据要求提供的更多信息:)

我曾经遇到过几次这样的情况,例如......我正在对 django-cron 进行黑客攻击,并确定有必要确保加载 django 时不存在现有作业(因为它会搜索所有已安装的应用程序以查找作业并将它们添加到加载中)。

所以我在顶部添加了以下代码 __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

出于明显的原因,这是垃圾。它与 sqlite 绑定在一起,我有更好的地方可以放置此代码(这就是我遇到这个问题的方式),但它有效。

正如你所看到的,你得到的错误是操作错误(在 sqlite 中),并且堆栈跟踪显示了类似“table django_cron_job not found”的内容

解决方案

最终的目标是 在加载任何页面之前运行一些代码.

这可以通过在 urls.py 文件中执行它来完成,因为必须在提供页面之前导入它(显然)。

我能够删除那个丑陋的 try/ except 块:) 感谢上帝(还有 S.洛特)

有帮助吗?

解决方案

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

绝不。

如果您有在创建表之前访问模型的代码,那么您就会遇到很大的问题。你可能正在做一些严重错误的事情。

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

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

您(通常)不需要代码 __init__.py 模块。你(几乎)永远不应该拥有在一个程序中真正起作用的可执行代码。 __init__.py 模块。这是非常非常罕见的,并且不适合 Django。

我不知道你为什么要搞乱 __init__.py 什么时候 姜戈·克朗 说你的日程安排是在 urls.py.


编辑

清除记录是一回事。

胡闹与 __init__.py 和 Django-cron 的 base.py 显然是完全错误的方法来做到这一点。如果这么复杂,那你就错了。

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

你的 urls.py 只能在syncdb之后并且在所有ORM材料已正确配置和绑定之后运行。

你的 urls.py 例如,可以删除一些行,然后向表中添加一些行。至此,所有的syncdb问题都迎刃而解了。

你为什么没有你的逻辑 urls.py?

其他提示

这是试图产生它们几乎可以只在模块级之前就存在访问模型代码;它必须是在模块导入,为您的例子表明可执行代码运行。这一点,因为你已经猜到了,通过执行syncdb的原因而失败。它试图导入模块,但在导入模块的行为会导致应用程序级的代码来执行;一个“副作用”如果你愿意。

,以避免模块导入引起的副作用的需求如此强烈在Python,对于可执行Python脚本的if __name__ == '__main__':惯例已经变得司空见惯。当刚刚加载代码库会导致应用程序开始执行,头痛随之发生: - )

有关的Django应用,这成为头痛不止。考虑执行的每个模块的导入时间为oldJob.delete()的效果。它可能看起来就像当你用Django开发服务器运行它只执行一次,但在生产环境中它会被经常执行。如果您使用Apache,例如,Apache会经常火起来的几个子进程等着来处理请求。作为一个长期运行的服务器的推移,你的Django应用程序将得到自举每次处理分叉为Web服务器的时间,这意味着该模块将被导入,delete()将被调用几次,往往不可预测。的信号不会帮助,不幸的是,随着信号可以每隔一个Apache过程被初始化以及时间被触发。

有没有,顺便说一句,只是说可能会导致你的代码会在无意中执行一个网络服务器。如果您使用的工具,如epydoc的,例如,它们将导入您的代码来生成API文档。这反过来会导致应用程序逻辑开始执行,这显然只是运行一个文件分析器不希望的副作用。

由于这个原因,像这样的清理代码是最好的一个cron作业,它会查找过时的工作定期和清理DB处理。这个自定义脚本也可以手动运行,或通过任何工艺(部署过程中,例如,或作为您的单元测试setUp()功能,保证一个干净的测试运行的一部分)。不管你怎么做,重要的一点是像这样的代码应该总是被执行的明确的,而不是的隐含的作为打开源文件的结果。

我希望有所帮助。我知道它并没有提供一种方法来确定是否执行syncdb正在运行,但如果你在考虑生产部署设计你的Django应用程序的执行syncdb问题会奇迹般地消失了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top