2011-05-02 75 views
8

有沒有辦法將CharField更改爲TextField並保持來自此列的數據不變?Django:將CharField轉換爲TextField且數據完好

現在,我有以下幾點:

class TestLog(models.Model): 
    failed_reqs = models.CharField(max_length=DB_MAX_CHAR_LENGTH, blank=True) 
    passed_reqs = models.CharField(max_length=DB_MAX_CHAR_LENGTH, blank=True) 

但DB_MAX_CHAR_LENGTH是500,事實證明這一領域有時會超過這一點,所以我想去:

class TestLog(models.Model): 
    failed_reqs = models.TextField(blank=True) 
    passed_reqs = models.TextField(blank=True) 

我如何做到這一點,並保持我的數據完整的生產數據庫?

Djangobook詳細說明如何添加和刪除字段,並且我試着用South來做到這一點,但是South給了我一個錯誤,並且在錯誤出現之前查看輸出,好像South正在下降並且重新創建數據庫。這是南方的data migrations是關於什麼?

+0

這是關於數據庫限制的問題,但是在查看如何顯示模型字段爲textarea而不是input [type = text]時,我發現此問題。如果您只希望表單使用不同的HTML控件,請參閱:https://docs.djangoproject.com/en/dev/ref/forms/widgets/#specifying-widgets。如果問題更深入(如問題中) - 去南方奇蹟。 – 2013-03-08 16:31:00

回答

6

假設你有對數據庫的訪問,你提到的Django談論添加和刪除列的方式,我列出了兩個PostgreSQL和MySQL的方法,因爲你沒有提到你使用的是什麼。

Postgresql: 
BEGIN; 
    ALTER TABLE "TestLog" 
     ALTER COLUMN "failed_reqs" TYPE TEXT, 
     ALTER COLUMN "passed_reqs" TYPE TEXT; 
COMMIT; 

MySQL: 
BEGIN; 
    ALTER TABLE TestLog 
     MODIFY failed_reqs TEXT NULL, 
     MODIFY passed_reqs TEXT NULL; 
COMMIT; 

我強烈建議在做這些更改之前備份數據庫。

+1

很好,謝謝。 – Nathan 2011-05-04 19:23:47

5

副手,我會繼續研究南方的做法。這是我會嘗試的工作流程:

1)南模式遷移創建兩個新的TextField字段,稱爲「failed_reqs_txt」和「passed_reqs_txt」。

2)創建一個數據遷移從舊的字段中的數據遷移到新的領域

3)創建一個模式遷移,刪除原有的「failed_reqs」和「passed_reqs」領域。

----如果你需要的字段是相同的名稱與原始,我會再繼續:

4)創建模式遷移添加「failed_reqs」和「passed_reqs」爲的TextField

5)創建數據遷移以從「failed_reqs_txt」和「passed_reqs_txt」遷移到「failed_reqs」和「passed_reqs」字段。

6)創建模式遷移以刪除「failed_reqs_txt」和「passed_reqs_txt」字段。

雖然這是很多遷移,但它將每個更改分解爲原子遷移。我會先試試這個。我不確定爲什麼South會丟棄並重新創建數據庫。在向項目添加南方時是否運行了convert_to_south選項?我認爲這會導致遷移並讓南方知道它正在與現有項目合作,而不是新項目。

作爲一種替代方法,您可以直接對數據庫執行ALTERS以更改列類型,然後將Model.py從CharField更新爲TextField。 Postgres,據說支持以這種方式隱式地改變數據類型。 (見5.5.6節)我不確定關於mysql,但我認爲它的工作原理是一樣的。 (CharField到TextFiled應該是一個兼容的轉換)

無論如何,我會在做任何這樣的改變之前備份我的數據。希望這可以幫助。

+0

謝謝,事實證明這很容易直接通過Toad和/或SQL語句直接切換數據庫,但我們將來需要使用South,所以我很欣賞這種寫法。 – Nathan 2011-05-04 19:23:37

+1

這是正確的方式,適用於不同的底層數據庫。即使看起來這麼長,它也是非常合乎邏輯的。可能只有3個縮影:1)模式+數據:創建字段,使用舊值初始化它們,2)轉儲舊字段,3)將新字段重命名爲舊名稱。我不確定,但你甚至可以在2次遷徙中做到這一點,甚至可以在壓力不大的情況下寫下逆向遷徙。 – 2013-03-08 16:27:59

5

這是用django遷移(1.7+)解決的。如果您將類型從CharField更改爲TextField,則生成的遷移是AlterField,這是正確的。