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自动生成列?
从hrbrmstr评论中的帖子中,我发现了一个黑客来完成这项工作.
在postgresqlWriteTable中RPostgreSQL包,你需要更换线
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)
| 归档时间: |
|
| 查看次数: |
3157 次 |
| 最近记录: |