2017-01-16 32 views
1

我有一個使用bradjasper的django-jsonfield包的Postgres 9.4/Django 1.8數據庫。 (請參閱https://github.com/bradjasper/django-jsonfield)它運行良好,但我想升級現有數據以使用Postgres 9.6和Django 1.9的內置JSONField。 (請參閱https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#jsonfield)這將允許對JSON內容進行更強大的搜索。我應該如何從bradjasper的django-jsonfield升級到Django的內置jsonfield?

如何將舊數據庫升級到新數據庫?

我已經試過: 我試着將一對架構遷移到

  • 轉換的bradjasper JSONField到TextField,包括運行遷移。 (這應該不會改變數據庫,因爲bradjasper將數據存儲爲字符串。)
  • 運行Django的dumpdata命令。
  • 已更新Postgres & Django版本。
  • 運行遷移將TextField轉換爲Django的JSONField。 (這應該是數據庫中的更改,從textjsonjsonb。)
  • 運行Django的loaddata命令。這給出了一個錯誤,如:u"[] (type <type 'unicode'>) is not a valid list for field url_methods"]: (myapp.mytable:pk=1) field_value was '[]' 我正在看postgresql migrating JSON to JSONBUpgrade PostgreSQL JSON column to JSONB?但我希望最小化自定義SQL。
+0

你也可以編輯/刪除現有的遷移?在做loaddata之前? – Sayse

+0

我在dumpdata之前通過convert-to-textfield步驟運行遷移,然後在loaddata之前運行convert-from-textfield遷移。編輯步驟 - 嘗試一下,以便更清楚。 –

回答

2

從@tometzky經由Upgrade PostgreSQL JSON column to JSONB? 的ALTER COLUMN命令執行此具有令人驚訝的小麻煩:

  • 須藤-u postgres的PSQL -c「ALTER TABLE MyTable的ALTER COLUMN 「MyField的」 TYPE jsonb USING 「MyField的」: :文本:: jsonb;」 mydatabase

我不需要Django的loaddata/dumpdata命令或自定義遷移。

我確實有一些問題得到pg_upgrade工作,我想要的方式,因爲它不是默認的路徑上,並想改變在升級過程中使用的一個Postgres的端口。爲了解決,我做了以下內容:

  • pg_ctl -D /etc/postgresql/9.4/main/停止
  • 在postgresql.conf中使用sed去改變它使用哪個端口
  • 安裝Postgres的9.6
  • pg_ctl -D /etc/postgresql/9.6/main/停止
  • CD /無功/日誌/ PostgreSQL的
  • 運行pg_upgrade
  • CD回到原來的工作目錄
  • 易於得到-y刪除的PostgreSQL-9.4 PostgreSQL的客戶端,9.4的PostgreSQL服務器-DEV-9.4
  • 服務的PostgreSQL啓動
4

首先升級Postgres。如果所有的作品都升級了Django。

只有當一切按預期工作時,您才能開始編寫字段遷移。

你想從去:

from jsonfield import JSONField 

class MyModel(models.Model): 
    json = JSONField() 

要:

from django.contrib.postgres.fields import JSONField 

class MyModel(models.Model): 
    json = JSONField() 

步驟:

  1. 添加一個名爲json_new新的Postgres JSON領域。
  2. 進行遷移。不要遷移。
  3. 潛入遷移文件並編寫數據遷移(RunPython)來填充新的json字段。
  4. 進行遷移。
  5. 刪除舊字段。刪除舊的導入。
  6. 進行遷移,遷移。
  7. 將新字段重命名爲舊字段名稱。 json_new>json
  8. 進行遷移,遷移。
  9. 完成。

第1步:

使用import ... as ...防止碰撞。您的模型看起來像:

from jsonfield import JSONField as OldJSONField 
from django.contrib.postgres.fields import JSONField 

class MyModel(models.Model): 
    json = OldJSONField() 
    json_new = JSONField() 

第3步:

您需要RunPython在遷移看到https://docs.djangoproject.com/en/1.10/ref/migration-operations/#runpython 還要注意如何導入模型。

實際的數據遷移將是這樣的:

for obj in MyModel.objects.all() 
    obj.json_new = obj.json 
    obj.save() 

步驟4 - 7:

確保您創建刪除和重命名單獨的遷移。如果你做的所有代碼更改,並創建一個單一的遷移,那麼Django會認爲你下降json_new。但是你要刪除json和重命名json_newjson。小,但重要的區別。

它是不是要拼命降低遷移步驟。但是這需要手工編寫一些代碼。我很懶,喜歡Django爲我寫這段代碼。

+0

我喜歡你沒有自定義SQL就滿足了我這樣做的軟要求,但是對單個記錄的循環困擾了我。 (我在不同的表格上有幾個字段,每個表格可能有幾千條記錄)。另外SQL比我想象的要容易。我放棄了大拇指,但接受了我自己的答案。 –