【问题标题】:Django: Is there a way to retrieve ORM for past migration states?Django:有没有办法为过去的迁移状态检索 ORM?
【发布时间】:2016-02-02 20:12:31
【问题描述】:

假设你有一个 Django 模型:

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

然后你将它迁移到:

from django.db import models

class Person(models.Model):
    both_names = models.CharField(max_length=30)

您可能会为这种情况编写数据迁移(或我的,不是上述情况,但与问题相似且不可信)并且您肯定想对其进行测试。

我使用 call_command('migrate', app, state) 将数据库回滚到旧状态,然后我想我只需使用 Person 的历史 ORM 来实例化一些 Person 对象,然后进行迁移,然后进行一些断言检查我的数据迁移是否正常。

South 中,您只需通过Migration 调用旧的ORM。在Django 1.8 中如何做到这一点?

我的策略基于此文档:https://micknelson.wordpress.com/2013/03/01/testing-django-migrations/ 我希望找到 Django 的 historic-models 的实现:https://docs.djangoproject.com/en/1.8/topics/migrations/#historical-models

重申这个问题 - 我将如何获得 Person 的“旧”状态,以便创建一个像这样的人:Person(first_name='bob', last_name='jones') - 用于测试目的。

【问题讨论】:

    标签: python django orm django-south


    【解决方案1】:

    公共 API 不提供任何方法来获取迁移之外的历史模型。但是,您可以使用以下代码获取它:

    from django.db import connection
    from django.db.migrations.loader import MigrationLoader
    
    loader = MigrationLoader(connection)
    state = loader.project_state(loader.applied_migrations)
    apps = state.apps
    

    appsRunPython 操作中传递给函数的对象相同。您可以使用 apps.get_model('<app_label>', '<ModelName>') 获取当前应用的迁移的历史模型。

    这应该适用于 1.8 和 1.9。它在未来的版本中可能会或可能不会起作用,尽管我看不出为什么这部分 API 应该很快改变。

    【讨论】:

      【解决方案2】:

      对于 Django 3.0 和 3.1 ,解决方案与 @knbk 的答案基本相同,除了 project_state() 的输入参数只是像 ('<APP_LABEL>', '<MIGRATION_NAME>') 这样的元组,而不是整个 applied_migrations 字典。

      您可以通过直接指定<APP_LABEL><MIGRATION_NAME> 来获取指定应用程序从初始迁移到特定提交迁移的状态:

      from django.db import connection
      from django.db.migrations.loader import MigrationLoader
      
      loader = MigrationLoader(connection)
      state = loader.project_state(('your_app_label', '0023_alter_some_fields'))
      apps = state.apps
      

      注意上面的代码在运行迁移命令时不能使用(例如makemigrationssqlmigratemigrate),否则会导致递归调用栈错误。

      【讨论】:

        猜你喜欢
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-15
        • 1970-01-01
        • 1970-01-01
        • 2012-01-02
        • 1970-01-01
        相关资源
        最近更新 更多