2014-03-03 47 views
9

RPostgreSQL中的dbWriteTable函数似乎忽略列名称,并尝试按原样将数据从R推送到PostgreSQL。当附加到现有表时,这是有问题的,特别是如果在R对象中有未指定的列应被赋予默认值。如何在RPostgreSQL中使用dbWriteTable(...,append = TRUE)列缺省值

RMySQL通过将列名LOAD DATA LOCAL INFILE非常优雅地处理这种情况。如何强制RPostgreSQL到默认值分配给未指定的列在dbWriteTableappend=TRUE

下面是一个例子:

CREATE TABLE test (
    column_a varchar(255) not null default 'hello', 
    column_b integer not null 
    ); 
insert into test values (DEFAULT, 1); 

下表对其产生:

select * from test; 
column_a | column_b 
----------+---------- 
hello |  1 
(1 row) 

我想来自R插入一些新的数据到这个表:

require('RPostgreSQL') 
driver <- PostgreSQL() 
con <- dbConnect(driver, host='localhost', dbname='development') 
set.seed(42) 
x <- data.frame(column_b=sample(1:100, 10)) 
dbWriteTable(con, name='test', value=x, append=TRUE, row.names=FALSE) 
dbDisconnect(con) 

但我得到以下错误:

Error in postgresqlgetResult(new.con) : 
    RS-DBI driver: (could not Retrieve the result : ERROR: missing data for 
column "column_b" 
CONTEXT: COPY test, line 1: "92" 
) 

这是因为我没有指定column_a字段,因此dbWriteTable正在尝试将column_b的数据写入column_a。我想迫使dbWriteTable使用默认值column_a,妥善写column_bcolumn_b

我是否应该只得到一个错误:

  1. 我不能没有默认值指定列
  2. 我尝试插入不在表
  3. 我插入存在的列将错误的数据类型转换为现有列
+0

如果你写了一个创建表的小例子,然后试图追加它,它会有帮助。 – nograpes

+1

@nograpes完成。查看编辑的问题。 – Zach

+0

当使用'x < - data.frame(column_a ='hello',column_b = sample(1:100,10))'时会发生什么?我不确定是否支持默认值......另一种方法是发送实际的SQL'insert'语句,而不是依赖'dbWriteTable'。 –

回答

7

我有完全相同的问题,这解决了它。

退房的dbWriteTable2功能从包caroline

然后,该代码允许您使用add_id = TRUE,例如写数据帧没有id列到数据库

dbWriteTable2(con_psql,"domains",data_domains,append=TRUE,overwrite=FALSE,row.names=FALSE,add.id=TRUE) 
+0

它是否将列名添加到插入语句中,以便它们不需要处于相同的顺序? – Zach

+0

当我使用它时,我在我的数据框中以相同的顺序匹配了列名。我在数据框中遗漏的唯一一列是“id”。 – Alex

+0

新测试:以随机顺序+额外的列编写列。这一切都奏效了,它甚至处理了额外的专栏:'找到'网址'不在'排名'表中的字段。忽略。“ – Alex