[英]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_to
和dplyr
,但是我也收到錯誤。
毫不奇怪,看到了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.