2016-01-17 83 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") 

這將內存管理責任放在似乎解決了您的問題的數據庫上。

展望未來,我會建議您嘗試總是下滲什麼是從數據庫返回僅是實際需要(是通過剪接或過濾)