2017-04-13 81 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) 

祝你好運:)