如何使用自动增量主键将数据从R写入PostgreSQL表?

Ric*_*ton 11 postgresql r

我在PostgreSQL数据库中有一个表,它有一个BIGSERIAL自动递增的主键.重新使用:

CREATE TABLE foo
(
  "Id" bigserial PRIMARY KEY,
  "SomeData" text NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

我想通过RPostgreSQL包从R中将一些数据附加到此表中.在R中,数据不包括Id列,因为我希望数据库生成这些值.

dfr <- data.frame(SomeData = letters)
Run Code Online (Sandbox Code Playgroud)

这是我用来尝试编写数据的代码:

library(RPostgreSQL)
conn <- dbConnect(
  "PostgreSQL", 
  user     = "yourname", 
  password = "your password",
  dbname   = "test"
)
dbWriteTable(conn, "foo", dfr, append = TRUE, row.names = FALSE)
dbDisconnect(conn)
Run Code Online (Sandbox Code Playgroud)

不幸的是,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"
## )
Run Code Online (Sandbox Code Playgroud)

错误消息并不完全清楚,但我将其解释为R试图将SomeData列的内容传递给数据库中的第一列(即Id).

我应该如何将数据传递给PostgreSQL以便Id自动生成列?

Ric*_*ton 7

从hrbrmstr评论中的帖子中,我发现了一个黑客来完成这项工作.

postgresqlWriteTableRPostgreSQL包,你需要更换线

sql4 <- paste("COPY", postgresqlTableRef(name), "FROM STDIN")
Run Code Online (Sandbox Code Playgroud)

sql4 <- paste(
  "COPY ", 
  postgresqlTableRef(name), 
  "(", 
  paste(postgresqlQuoteId(names(value)), collapse = ","), 
  ") FROM STDIN"
)
Run Code Online (Sandbox Code Playgroud)

请注意,引用变量(未包含在原始hack中)对于传递区分大小写的列名称是必需的.

这是一个脚本:

body_lines <- deparse(body(RPostgreSQL::postgresqlWriteTable))
new_body_lines <- sub(
  'postgresqlTableRef(name), "FROM STDIN")', 
  'postgresqlTableRef(name), "(", paste(shQuote(names(value)), collapse = ","), ") 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")
Run Code Online (Sandbox Code Playgroud)

  • 您可能更容易下载软件包源代码,编辑R函数,然后安装修改后的版本. (2认同)