簡體   English   中英

如何在R&MonetDB中管理模式?

[英]How to manage schemas in R & MonetDB?

我最近問了一個類似的問題,更適合dplyr。

請參閱dplyr和monetdb-用於查詢schema.table的適當語法?

由於dplyr和MonetDB(根據上述@HannesMühleisen的回復)沒有適當的方法來管理模式,因此我決定使用MonetDB.R / DBI本機函數。

同樣在這種情況下,結果也有些問題:看來,此時MonetDB.R能夠正確地管理每個數據庫一個模式。

讓我們看一些代碼。 我創建兩個架構,並且在每個架構中創建相同的表名(標准sql做法)。 然后,我嘗試將數據寫入每個。

> conn <– dbConnect(MonetDB.R(), "db.url", user= "monetdb", password="monetdb")
> df <- data.frame(i=10,j=20)
> q <- dbGetQuery(conn, "CREATE SCHEMA foo;")
> q <- dbGetQuery(conn, "SET SCHEMA foo;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")
> q <- dbWriteTable(conn,  "mytable",df,overwrite=TRUE)
> q <- dbGetQuery(conn, "CREATE SCHEMA bar;")
> q <- dbGetQuery(conn, "SET SCHEMA bar;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")

在這一階段,我應該有兩個具有相同名稱但在兩個不同模式中的表。 dbListTables確認了這一點(很高興看到這些架構,但沒有它我可以活下來):

> dbListTables(conn)
[1] "mytable" "mytable"

但是,一旦我嘗試使用與以前使用的查詢相同的查詢來寫入mytable,那就麻煩了!

> q <- dbWriteTable(conn,  "mytable",df,overwrite=TRUE)
Error in .local(conn, statement, ...) : 
  Unable to execute statement 'INSERT INTO mytable VALUES (10, 20)'.
Server says 'INSERT INTO: no such table 'mytable'' [#42S02].

此時,DB處於混亂狀態,並要求回滾事務。

讓我們嘗試overwrite = FALSE,只是看看是否有什么不同:

> df <- data.frame(i=10,j=20)
> q <- dbGetQuery(conn, "CREATE SCHEMA foo;")
> q <- dbGetQuery(conn, "SET SCHEMA foo;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")
> q <- dbWriteTable(conn,  "mytable",df,overwrite=TRUE)
> q <- dbGetQuery(conn, "CREATE SCHEMA bar;")
> q <- dbGetQuery(conn, "SET SCHEMA bar;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")
> dbListTables(conn)
[1] "mytable" "mytable"
> q <- dbWriteTable(conn,  "mytable",df,overwrite=FALSE)
Error in .local(conn, name, value, ...) : 
  Table mytable already exists. Set overwrite=TRUE if you want 
      to remove the existing table. Set append=TRUE if you would like to add the new data to the 
      existing table.

我已經用append=true擊中了母體

> df <- data.frame(i=10,j=20)
> q <- dbGetQuery(conn, "CREATE SCHEMA foo;")
> q <- dbGetQuery(conn, "SET SCHEMA foo;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")
> q <- dbWriteTable(conn,  "mytable",df,overwrite=TRUE)
> q <- dbGetQuery(conn, "CREATE SCHEMA bar;")
> q <- dbGetQuery(conn, "SET SCHEMA bar;")
> q <- dbGetQuery(conn, "CREATE TABLE mytable (i int, j int);")
> dbListTables(conn)
[1] "mytable" "mytable"
> q <- dbWriteTable(conn,  "mytable",df,append=TRUE)

后面的順序似乎可以正常工作,並且可以將數據加載到條形圖中,而不會出現問題。 但是,您是否使用了(如我通常所做的那樣) csvdump=TRUE ,則出現另一個錯誤:

Error in .local(conn, statement, ...) : 
Unable to execute statement 'COPY 15 RECORDS INTO mytable FROM '/var/folders/m4/yfyjwcpj6rv5nq730bl9vr1h000...'.
Server says 'COPY INTO: no such table 'mytable'' [#42S02].

我總是可以避免使用csvdump但是我需要編寫大表...

我也嘗試了copy_todplyr ,但是我也收到錯誤。

毫不奇怪,看到了csvdump的問題,我也使用monetdb.read.csv遇到了類似的錯誤:如果在另一個模式中存在相同的名稱表時嘗試加載一個csv,則會出現錯誤。

難道我做錯了什么? 有更好的做事方法嗎? 這是錯誤嗎?

歡迎任何幫助。

當我需要找到解決方案時,我最終重新編寫/重構了MonetDB.R中的所有主要標准功能。

作為一個簡單的示例,這是代替dbListTables的代碼:

fdblisttables <- function(conn, schema){ 
  q <- dbGetQuery(conn, paste0("SELECT s.name AS name FROM sys.tables AS s
                               JOIN sys.schemas AS t ON s.schema_id=t.id WHERE t.name='", schema,"';" ))
  if(is.null(q$name)) q <- character() else q <- q$name    
}

公平地說,真正的問題是DBI沒有適用於模式的語法(但如果有……的話,那會很好),因此MonetDB.R庫開發人員的編程手是有聯系的。

我意識到模式可以至少以兩種方式實現:

  • 隱式地,但是它將需要一種從數據庫中獲取current schema ,當前在monetdb不可用(並且可能在其他數據庫中都不可用)
  • 明確地,將關鍵字模式添加到函數調用中。 最后,這就是我所做的,因為這是最簡單的方法。 另一方面,存在與現有代碼等兼容的問題。

和往常一樣,任何建議和幫助都值得歡迎。 如果有興趣,我將在github的要點上發布我創建的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM