2013-11-25 34 views
2

我剛剛閱讀了=>運營商的hstore擴展is deprecated and might be removed in future versions。這是壞消息,因爲我有幾個函數在 依賴使用此運算符時存儲到包含hstore字段的Postgres表中。Postgres:如何處理已棄用的hstore運營商:「=>」

在寫入數據庫之前,我在內存中準備了一個data.framedata.table(R會話)。 隨後,我只需使用便捷功能dbWriteTable將整個表內存寫入數據庫。因此,使用postgres函數hstore(文本,文本)會很不方便。

什麼是處理這種公告的好策略?我很驚訝他們正在移除運營商,因爲肯定有相當一部分人正在與其他類型的字段一起寫入hstore。這也不是真正的R特定。它是許多語言相同的問題..

雖然我走到這一步,一些有用的見解,也許這有助於澄清我的問題是什麼:

我添加了一個重複的例子,用於R鄉親和截圖爲世界其他.. enter image description here 我建立R中一個data.frame(基本上在存儲器中的表表示)是這樣的:

mydf <- structure(list(ts_key = c("somekey", 
         "somekey"), ts_language = c("de", "en" 
        ), ts_labels = c("\"Kurztitel\" => \"Wohlbefinden\",\"mögliche_Antworten\" => \"fantastisch,so lala,total fertig\",\"Wortlaut\" => \"Wie geht es?\"", 
             "\"available_items\" => \"awesome,somewhat ok,wasted\",\"short_title\" => \"well being\",\"wording\" => \"How are you?\"" 
        )), .Names = c("ts_key", "ts_language", "ts_labels"), row.names = c(NA, 
                          -2L), class = "data.frame") 

所以存儲器表/ data.frame含有hstore作爲字符作爲其中一列。 這是非常方便,因爲我可以有很多行的data.frame,然後簡單地使用:

dbWriteTable(myconnection,"somePostgresTableWithTheRightStructure",mydf,append=T) 

,只是寫了整個data.frame的分貝,而無需構建查詢或顯式循環。我很想保留這個,但我不知道如何告訴dbWriteTable使用hstore(文本,文本)。

+2

你能寫一個'=>'的包裝器,並將它作爲權宜之計包含在你的包中,直到你可以遷移你的代碼? –

+0

目前,一切正常。我有這個功能:https://github.com/mbannert/pgsqltsmap/blob/master/R/create_hstore.R 創建一個字符表示,所以我可以有一個數據。包含(其他)hstore列的框架。你是這個意思嗎?我只是不想離開使用dbWriteTable並且不得不創建大量的單個INSERT。 –

+0

我的意思是基本上將'=>'函數導入到你的包中,但是從@Denis的評論看來,它會導致SQL出現問題。 –

回答

2

它實際上並不特定於hstore:它也會影響其他自定義操作符。其removal in 9.2的推理是the SQL standard now reserves that token

什麼是處理這種通告的好策略?

考慮切換到使用json。它有一個類似的->運算符,一組類似的函數,我想你已經有了R庫,可以從一個對象轉到json並返回。在數據庫級別,更改僅涉及cast from hstore to json(請參閱json文檔頁面上的最後一個註釋)。

+0

+1幫助我瞭解移除情況並判斷它是否即將消失。事實上,R到json和back在R中工作得很好。我仍然得不到的是:爲了能夠使用我的批量導入功能,我必須將我的data.table寫入數據庫(以避免多個單獨的INSERT查詢)。因此假設,如果它包含'json'而不是使用'=>'的hstore的字符表示,我可以在觸發一個類似於你之後建議的投影時將它存儲到數據庫中嗎? –

+0

如果你的表包含一個json列,比如你可以直接插入json的文本表示(當然,它提供的格式良好),就像你對日期或時間戳一樣。 (僞代碼,但你會希望得到的)所以,當運行類似於'db.query(「insert into foo(bar)values?)」,str)',而不是構建一個hstore字符串像'str = 'a => 1'',你會創建一個像str = JSON.new(a:1).to_s'這樣的json對象。 –

+0

感謝您的解釋。我剛剛添加了一段代碼和截圖來說明'dbWriteTable'的問題。也許實際上建立一個JSON字符串,存儲到pg,然後觸發轉換可能是一個解決方案。 –

3

只有運營商正在被刪除,而不是基礎功能。因此,而不是

a => b 

hstore(a, b) 

的這是完全向後兼容。所以,今天就修改你的代碼並完成。

+0

這只是問題所在。我有很多使用'dbWriteTable'的優點,因此不希望顯式運行INSERT語句。如果可能,需要在內存中準備一個字符串。 –

+0

什麼阻止你這麼做? –