2014-10-28 33 views
14

我在應用程序中創建了一些動態Django模型,除遷移系統外,一切似乎都按預期工作。Django 1.7 - makemigrations爲非託管模型創建遷移

如果我創建一個動態Django模型並設置managed = False,Django的makemigrations命令仍然會爲該新模型生成一個遷移。遷移看起來是這樣的:

class Migration(migrations.Migration): 

    dependencies = [ 
     ('atom', '0001_initial'), 
    ] 

    operations = [ 
     migrations.CreateModel(
      name='books', 
      fields=[ 
      ], 
      options={ 
       'db_table': 'books', 
       'managed': False, 
      }, 
      bases=(models.Model,), 
     ), 
    ] 

如果我沒有創建遷移,當我運行python manage.py migrate,我看到以下消息(在大的嚇人的紅色字母):

Your models have changes that are not yet reflected in a migration, and so won't be applied. 
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them. 

是有沒有辦法告訴Django 1.7中的遷移系統忽略非託管模型?或者在模型的Meta類中設置了migrations = False

更新:澄清,我使用的方法創建我相似的人的動態模型描述在以下地方:

這方法非常適合基於存儲在我的配置模型(https://code.djangoproject.com/wiki/DynamicModels#Adatabase-drivenapproach)中的信息生成我的動態模型。我確實需要註冊一個信號來清除django模型緩存,以便在更改配置實例時捕獲對模型的更改,但似乎一切正常,除了爲這些模型生成遷移。如果我刪除其中一個配置並從Django的緩存中刪除模型,則需要再次更新遷移,刪除它不應該關心的模型。

這些動態模型沒有專門用於應用程序。沒有在代碼中的哪個地方指的是書籍模型(來自上面的例子)。它們在運行時生成,用於從他們提供訪問的舊錶中讀取信息。

+0

但是,遷移實際上是否導致問題?也就是說,當你運行'migrate'時,是否會錯誤地在數據庫中創建模型?如果沒有,那真的沒有問題。遷移系統不僅關注數據庫級別的更改,還會盡可能準確地創建內存模型的圖像。 – 2014-10-28 18:45:10

+0

這是正確的。遷移不會造成問題。但是,在動態系統中,始終存在潛在的新模型。如果我可以向遷移系統表明它不需要擔心這些特定模型,那將會很好。 – chadgh 2014-10-28 19:32:22

+0

您能否向我們提供有關您的動態模型如何生成的更多細節?主要需要哪些數據來動態生成它們。 – 2014-11-05 15:52:21

回答

4

簡短的回答是,Django不是爲此而構建的。讓您的模型「非託管」only means Django will not create or delete the table for it -- nothing else

也就是說,如果你沒有定期模型一起在相同的應用程序,這些動態模型,你可以有條件地將應用程序添加到INSTALLED_APPSsettings.py

if not ('makemigrations' in sys.argv or 'migrate' in sys.argv): 
    INSTALLED_APPS += (
     'app_with_dynamic_models', 
     'another_app_with_dynamic_models', 
    ) 

這應該使創建時的Django忽略了應用程序和運行遷移。但是,如果要使用它們,最終必須爲模型創建和運行遷移,因爲從the ability to have apps which do not use migrations is meant to go away in Django 1.9開始。你的動態模型可以重構使用contenttypes framework

+0

這是一個拯救生命的,謝謝! – arctelix 2015-10-29 00:18:51

+0

在Django 1.11.5上失敗。 Django仍會嘗試在包含非託管表的遺留數據庫中創建django_migrations表。 – user1255933 2017-09-26 18:41:41

1

您可以編寫自定義數據庫路由器,allow_migrate方法爲您的動態模型返回False。在這種情況下,migrate命令將禁止它們。

只要您不在任何models.py模塊中加載這些動態模型,makemigrations也不應該選擇它們。

+1

那麼,這給了我更接近的東西,但它並不完全。當我運行makemigrations命令時,動態模型仍然被看到並且正在爲它們創建遷移。但是,它不會爲這些表/模型運行遷移。理想情況下,會有類似'allow_makemigrations'的方法,我也可以重寫。 – chadgh 2014-11-03 23:43:43

2

我建議你用自己的操作替換生成的migrations.CreateModel操作,該操作始終反映實際的模型狀態。這種方式不應該檢測到狀態變化。

class CreateDynamicModel(CreateModel): 
    def __init__(self): 
     # ... dynamically generate the name, fields, options and bases 
     super(CreateDynamicModel, self).super(
      name=name, fields=fields, options=optins, bases=bases 
     ) 
相關問題