23

I am creating some dynamic Django models in my application and everything seems to be working as expected except for the migration system.

If I create a dynamic Django model and set managed = False, Django's makemigrations command still generates a migration for that new model. The migration looks something like this:

class Migration(migrations.Migration):

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

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

If I don't create the migration, when I run python manage.py migrate, I see the following message (in big scary red letters):

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.

Is there a way to tell the migrations system in Django 1.7 to ignore unmanaged models all together? or perhaps a migrations = False setting in the Meta class of the models?

UPDATE: for clarification, I am using a method to create my dynamic models similar to the ones describe in the following places:

This method is great for generating my dynamic models based on information stored in my Configuration models (https://code.djangoproject.com/wiki/DynamicModels#Adatabase-drivenapproach). I did have to register a signal to clear the django model cache to catch changes to the models when a Configuration instance is changed, but everything seems to be working great, except for the fact that migrations are generated for these models. If I delete one of the configurations and the model is deleted from Django's cache, the migration would need to be updated again, removing the model that it shouldn't care about.

These dynamic models are not used in the application specifically. No where in the code do I refer to a books model (from the example above). They are generated at runtime and used to read information from the legacy tables they provide access to.

4

3 回答 3

5

简短的回答是 Django 不是为此而构建的。使您的模型“不受管理”仅意味着 Django 不会为其创建或删除表——仅此而已

也就是说,如果您在同一个应用程序中除了这些动态模型之外没有常规模型,您可以有条件地将应用程序添加到INSTALLED_APPSin settings.py

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

这应该使 Django 在创建和运行迁移时忽略该应用程序。然而,如果你想使用模型,你最终将不得不为模型创建和运行迁移,因为拥有不使用迁移的应用程序的能力意味着在 Django 1.9 中消失。您的动态模型可以重构为使用contenttypes 框架吗?

于 2014-11-06T21:26:37.553 回答
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
        )
于 2014-11-05T15:58:44.403 回答
1

您可能可以编写自定义数据库路由器,并为您的动态模型返回allow_migrate方法。False在这种情况下,该migrate命令将禁止它们。

只要您不在任何models.py模块中加载这些动态模型,makemigrations也不应将它们拾取。

于 2014-11-03T15:48:31.150 回答