我在Postgresql数据库中有一个表,它有一个BIGSERIAL自动递增主键.使用以下方法重新创建
CREATE TABLE foo ( "Id" bigserial PRIMARY KEY,"SomeData" text NOT NULL );
我想通过RPostgresql包从R向该表附加一些数据.在R中,数据不包括Id列,因为我希望数据库生成这些值.
dfr <- data.frame(SomeData = letters)
这是我用来尝试编写数据的代码:
library(RPostgresql) conn <- dbConnect( "Postgresql",user = "yourname",password = "your password",dbname = "test" ) dbWriteTable(conn,"foo",dfr,append = TRUE,row.names = FALSE) dbDisconnect(conn)
不幸的是,dbWriteTable抛出一个错误:
## Error in postgresqlgetResult(new.con) : ## RS-DBI driver: (could not Retrieve the result : ERROR: invalid input Syntax for integer: "a" ## CONTEXT: COPY foo,line 1,column Id: "a" ## )
从hrbrmstr评论中的帖子中,我找到了
a hack来完成这项工作.
在RPostgresql包中的postgresqlWriteTable中,您需要替换该行
sql4 <- paste("COPY",postgresqlTableRef(name),"FROM STDIN")
同
sql4 <- paste( "COPY ","(",paste(postgresqlQuoteId(names(value)),collapse = ","),") FROM STDIN" )
请注意,引用变量(未包含在原始hack中)对于传递区分大小写的列名称是必需的.
这是一个脚本:
body_lines <- deparse(body(RPostgresql::postgresqlWriteTable)) new_body_lines <- sub( 'postgresqlTableRef(name),"FROM STDIN")','postgresqlTableRef(name),paste(shQuote(names(value)),") FROM STDIN")',body_lines,fixed = TRUE ) fn <- RPostgresql::postgresqlWriteTable body(fn) <- parse(text = new_body_lines) while("RPostgresql" %in% search()) detach("package:RPostgresql") assignInNamespace("postgresqlWriteTable",fn,"RPostgresql")