2016-09-06 25 views
1

我想爲多租戶應用程序使用一個metadata JSONB列。每個租戶的每個user必須具有相同的metadata,但租戶有不同的metadata字段。Postgresql更新JSON列保留一些KeyValues並添加額外的KeyValue爲空

爲了讓所有用戶的元數據在每個租戶同步,當佔有者管理員修改我需要確保所有用戶都具有自己的元數據JSONB列如下標準更新元數據字段:

  1. 如果元數據字段/密鑰已存在,則需要保留該值
  2. 如果元數據字段/密鑰是新的,則密鑰需要添加空值
  3. 如果有任何元數據字段/密鑰未包含在更新的列表,它們應該從JSON對象中刪除

例如,Tenant#1的所有用戶都分配了以下元數據:{ "EmployeeNo" : 123, "HireDate" : "2012-10-10", "Age" : 43 }以及管理員決定他們不關心Age的某處,但他們確實想要開始跟蹤ParkingSpace。

我需要新的元數據記錄來保留EmployeeNo和HireDate值,刪除Age鍵/值,並添加一個null值的ParkingSpace鍵。 { "EmployeeNo" : 123, "HireDate" : "2012-10-10", "ParkingSpace" : null }

我本來以爲我可以運行類似的更新查詢以下的地方返回如果該鍵存在,如果它不空不到哪它選擇的值的JSONB對象:

UPDATE users SET metadata = metadata[keys: 'EmployeeNo', 'HireDate', 'ParkingSpace'] WHERE tenant_id = 1;

很明顯,這將無法正常工作,但希望它能指出問題所在?

回答

0

更新:我可能誤解了你的問題。也許你想這樣的事情,而不是:

UPDATE users 
SET metadata = (SELECT json_object_agg(n,metadata->>n) FROM unnest(ARRAY['EmployeeNo','HireDate','ParkingSpace']) AS t(n)) 

該解決方案包括僅提取您從原來的metadata所需的字段創建一個全新的jsonb對象。要複製的字段被指定爲可以輕鬆自定義的數組。

原來的答覆:我覺得這個應該這樣做:

UPDATE users 
SET metadata = (metadata - 'Age') || '{"ParkingSpace": null}'::jsonb; 

我使用||算子合併2名jsonb對象轉換成一個和-運營商則會刪除鍵/值對。

+0

我大概可以做到這一點,理想情況下我不想跟蹤被刪除的列(在這種情況下是'年齡')。 –

+0

我重讀了你的問題,我更新了我的答案。讓我知道這是否有效。 – redneb

+0

甜,你的更新答案似乎完美!現在,我將不得不通過關於* why * doc的文檔(特別是json_object_agg和unnest數組)。謝謝! –