2015-10-08 4 views
0

Недавно я задал аналогичный вопрос, более ориентированный на dplyr.Как управлять схемами в R & MonetDB?

См dplyr & monetdb - appropriate syntax for querying schema.table?

Как dplyr & MonetDB (по @Hannes Mü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]. 

На данный момент БД остается в беспорядочном состоянии и просит отменить транзакцию.

Давайте попробуем с перезаписью = 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, когда одна и та же таблица имен существует в другой схеме.

Я что-то не так? Есть ли лучший способ сделать что-то? Это ошибка?

Любая помощь приветствуется.

ответ

0

Поскольку мне нужно было найти решение, я закончил переписывать/реорганизовывать все основные стандартные функции в 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 (и, возможно, ни с другими dbs)
  • явно, добавляя схему ключевых слов к вызову функции. В конце концов, это то, что я сделал, поскольку это был самый простой способ. С другой стороны, это создает проблемы с совместимостью с существующим кодом и т. Д.

Как обычно, любые предложения и помощь приветствуются. Если есть интерес, я опубликую функции, которые я создал на gist в github.

Смежные вопросы