我最近问过一个类似的问题,更多是针对dplyr。
请参阅dplyr & monetdb - appropriate syntax for querying 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].
此时数据库处于凌乱状态,并要求回滚事务。
让我们尝试使用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)
后一个序列似乎可以正常工作并将数据加载到bar模式中而不会出现问题。
但是你使用(正如我通常那样)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
&amp; dplyr
,但我也遇到了错误。
毫不奇怪,看到csvdump
的问题我也使用monetdb.read.csv
得到了类似的错误:如果在另一个模式中存在同名表时尝试加载csv,则会出错。
我做错了吗?有更好的办法吗?这是一个错误吗?
欢迎任何帮助。
答案 0 :(得分:0)
当我需要找到解决方案时,我最终重新编写/重构了MonetDB.R中的所有主要标准函数。
作为一个简单示例,这是替换/**
* @Entity
* @Table(name="database_name.table_name")
*/
class YourEntity
的代码:
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
}
没有针对模式的语法(但如果它有......那就好了),所以{{1}的编程手库开发人员有点束缚。
我意识到模式可以至少以两种方式实现:
DBI
,MonetDB.R
目前不可用(并且可能两者都没有)像往常一样,欢迎任何建议和帮助。如果有兴趣,我会在github上的gist上发布我创建的函数。