代码之家  ›  专栏  ›  技术社区  ›  Jiaaro

在syncdb期间阻止代码运行

  •  1
  • Jiaaro  · 技术社区  · 17 年前

    我有一些抛出导致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中),堆栈跟踪显示了“TableDjango_cron_job not found”的内容

    解决方案

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

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

    而且我能够移除那个丑陋的尝试/例外块:)感谢上帝(还有S.洛特)

    2 回复  |  直到 16 年前
        1
  •  4
  •   S.Lott    17 年前

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

    从不

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

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

    __init__.py 单元您不应该(几乎)拥有在一个系统中真正工作的可执行代码 __初始值

    我不知道你为什么要惹我 __初始值 什么时候 Django Cron 说你是在 urls.py


    编辑

    清理记录是一回事。

    __初始值 还有Django cron's base.py

    你的

    你的 url.py

    你为什么不把你的逻辑放进去 url.py

        2
  •  2
  •   Jarret Hardie    17 年前

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

    if __name__ == '__main__': 可执行python脚本的约定已经很普遍。当仅仅加载一个代码库就导致应用程序开始执行时,随之而来的是令人头痛的问题:-)

    oldJob.delete() 每次导入模块时执行。在使用Django开发服务器运行时,它似乎只执行一次,但在生产环境中,它会经常执行。例如,如果您使用Apache,Apache将经常启动几个等待处理请求的子进程。随着长时间运行的服务器的发展,每次为您的web服务器派生处理程序时,您的Django应用程序都将得到引导,这意味着模块将被导入并重新启动 delete()

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

    因此,像这样的清理代码最好由cron作业来处理,它会定期查找过时的作业并清理数据库。此自定义脚本也可以手动运行,也可以由任何进程运行(例如在部署期间,或作为单元测试的一部分) setUp() 功能以确保干净的测试运行)。不管你怎么做,重要的一点是像这样的代码应该总是被执行 明确地 而不是 含蓄地

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