2017-04-13 51 views
4

我认为在最近版本的Django中有一个简单的答案,但我无法找到它。Django:在每次启动时运行代码,但在数据库迁移后运行代码

我有接触数据库的代码。每次Django启动时我都希望它运行。我似乎有两个选择:

选项1.AppConfig.ready() - 这工作,但数据库中创建表之前也运行(即在测试过程中或重新初始化没有数据的应用程序时)。如果我用这个我必须赶上多种类型的异常和猜测的原因是空的DB:

def is_db_init_error(e, table_name): 
    return ("{}' doesn't exist".format(table_name) in str(e) or 
      "no such table: {}".format(table_name) in str(e) 
    ) 

try: 
    # doing stuff 
except Exception as e: 
    if not is_db_init_error(e, 'foo'): 
     raise 
    else: 
     logger.warn("Skipping updating Foo object as db table doesn't exist") 

选项2使用post_migrate.connect(foo_init, sender=self) - 但这只是跑的时候我做了迁移。

选项3旧的方式 - 从urls.py称之为 - 我想保持这样的东西出来urls.py,我想AppConfig是一个真实路径

我为选项2迄今为止落户 - 我不喜欢臭的尝试/除了选项1和选项3的东西之外,我错误地将urls.py变成了垃圾场。

但是,当我在本地开发时,选项2经常让我出行 - 我需要记住在我希望运行init代码时运行迁移。像拉下生产数据库或类似的东西通常会导致问题,因为不会触发迁移。

+0

我还没有尝试过这个自己,但是你可以重写manage.py文件 – dentemm

回答

1

我建议connection_created信号,其是:

当数据库包装使得到 数据库的初始连接发送。如果您想将任何后连接命令 发送到SQL后端,此功能特别有用。

因此,它会在应用程序周期开始时应用程序连接到数据库时执行信号的代码。

它也将在多个数据库配置中的工作,甚至在初始化分开由应用程序所做的连接:

连接
已打开的数据库连接。这可以在多数据库配置中使用,以区分来自不同数据库的连接信号 。


注:
目前还不清楚,但极有可能的是,当你正在迁移connection_created信号将运行;当您迁移为好。也就是说,您可能需要考虑使用post_migrateconnection_created信号的组合,同时在您的AppConfig.ready()中检查是否发生迁移(例如,国旗的post_migrate信号的激活):

from django.apps import AppConfig 
from django.db.models.signals import post_migrate, connection_created 

migration_happened = false 

def post_migration_callback(sender, **kwargs): 
    ... 
    migration_happened = true 


def init_my_app(sender, connection): 
    ... 


class MyAppConfig(AppConfig): 
    ... 

    def ready(self): 
     post_migrate.connect(post_migration_callback, sender=self) 

     if !migration_happened: 
      connection_created.connect(init_my_app, sender=self) 

祝你好运:)