2016-01-17 59 views
5

我对Django非常有信心,但主要依赖生成的迁移直到最近。我写了一个小的自定义迁移,在我的CI开始抱怨超时之后不久,最终发现它与部署期间从Django迁移有关。Django迁移正在死亡

起初,我能解决这个问题,但我不知道我做了什么(如果有的话)修复它。这个问题似乎与我为特定迁移输入的一些自定义代码有关。这是我知道的:

  • 起初,一切都很好,但在迁移开始服用真的很长一段时间将我的自定义代码后运行(相对)。大约10秒钟。
  • 它有时会起作用。即。如果我从命令行运行十次迁移,有时会起作用,有时会失败。

输出如下(编辑了应用程序的名称):

[[email protected] myapp]$ ./manage.py migrate 
Operations to perform: 
    Apply all migrations: myapp1, myapp2, myapp3, myapp4 
Running migrations: 
Killed 
  • 起初我还以为是因为我使用RunPython运行Python函数前两个领域之间的数据复制删除其中一个字段。该文档不鼓励它用于PostgreSQL,但有没有更好的方法来做到这一点?
  • 这里的业务场景是我有一个布尔字段,我需要切换到一组选项(CharField与options)。代码检查布尔值是否为true并为字符字段设置正确的值。我做了两次。第一次最终结束工作,但我还没有在另一个数据库上测试过它。

这是迁移(编辑了应用程序的名称):

from __future__ import unicode_literals 

from django.db import migrations 

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    for m in my_model._default_manager.all(): 
     if m.consulting: 
      m.detail = "CONSLT" 
      m.save() 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('myapp', '0024_auto_20160117_1113'), 
    ] 

    operations = [ 
     migrations.RunPython(fix_consulting,atomic=False), 
    ] 

我的想法:

  • 也许我这里写代码的时间过长运行?数据库中有不到一百个模型,所以我不知道为什么fix_consulting函数需要这么长时间。

  • 如果我在fix_consulting的开头添加打印语句,它们只会有时运行,并且会在其他时间被杀死。既然这样,我已经跑了6-8倍,并且已经杀了所有的时间,但在不同的点

其他信息: - 使用Django 1.9 - 使用PostgreSQL 9.4.4 - 错误主要发生在CentOS上,但也是OSX

+0

它可能是你的机器只是不能存储由'all'检索的数据,因此可能将整个循环更改为'my_model._default_manager.filter(consulting = True).update(detail =“CONSLT”)'可能会解决此问题...我会如果我正确的话,很乐意让这个答案为 – Sayse

+1

我会给这个镜头!它是一个内存相当少的服务器。 –

+1

你是对的!这个错误是双重的。一旦我将它改为你提供的代码,它暴露了另一个很容易解决的错误,因为它实际上给了我一个堆栈跟踪。谢谢!继续并添加答案。 –

回答

7

我相信你的问题是由于使用all时可能需要缓存的数据量而引起的,因为这会返回对象的所有实例,因此可以对数据库执行过滤然后再返回对象,因为您只需要更改字段的值,您也可以在数据库级别更改值。总之,这会将您的代码更改为以下内容。

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    my_model._default_manager.filter(consulting=True).update(detail="CONSLT") 

这将内存管理责任放在似乎解决了您的问题的数据库上。

展望未来,我会建议您尝试总是下渗什么是从数据库返回仅是实际需要(是通过剪接或过滤)