2014-10-28 34 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 
     ) 
相关问题