使用 DBI 和 RPostgres 读/写 Postgres 大对象

Col*_*FAY 9 postgresql r rpostgresql

我正在尝试在 R 中使用 PostgreSQL 的大对象(https://www.postgresql.org/docs/10/largeobjects.html{DBI} )功能,但使用/编写和读取时遇到一些问题{RPostgres}

这是我到目前为止所尝试过的:

# Getting the db
docker run --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5433:5432 postgres
Run Code Online (Sandbox Code Playgroud)
library(DBI)
con <- dbConnect(
  RPostgres::Postgres(),
  dbname = "postgres",
  host = "localhost",
  port = 5433,
  user = "postgres",
  password = "mysecretpassword"
)
Run Code Online (Sandbox Code Playgroud)

创作作品:

> dbGetQuery(con, "SELECT lo_create(1234);")
  lo_create
1      1234
Run Code Online (Sandbox Code Playgroud)

但后来我很难弄清楚如何将 R 对象写入这个大对象。例如,我如何在 Postgres 中使用and编写mtcars一个大对象?{DBI}{RPostgres}

然后,我如何在 R 中再次读回它?

Par*_*ait 2

考虑使用 R serialize()(.RData/.RDS 格式的底层构建)将 R 对象保存到OID大型对象的 Postgres 列中,并使用 Postgres v10+服务器端大对象函数来创建和检索内容。下面可以bytea通过删除所有lo_*函数来处理类型。

假设表结构:

CREATE TABLE my_table(
   ...
   r_object OID
   ...
)
Run Code Online (Sandbox Code Playgroud)

要附加 R 对象:

# PREPARED STATEMENT
sql <- "INSERT INTO my_table(r_object) VALUES (lo_from_bytea(0, ?r_obj))"

# BIND PARAMETER OF SERIALIZED RAW VECTOR
query <- DBI::sqlInterpolate(conn, sql, r_obj = serialize(mtcars))

# EXECUTE ACTION
dbExecute(conn, query)
Run Code Online (Sandbox Code Playgroud)

要检索 R 对象:

sql <- "SELECT lo_get(r_object) AS r_data FROM my_table"
pg_data <- dbGetQuery(conn, sql)

# UNSERIALIZE RETURNED RAW VECTOR
mtcars_from_pg <- unserialize(pg_data$r_data[1])
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用 Postgres 的TEXT无限长度类型和 R 类型dput(R 对象的 ASCII 表示形式),并在返回的字符串上使用eval+ 。parsedput

CREATE TABLE my_table(
   ...
   r_text TEXT
   ...
)
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE my_table(
   ...
   r_text TEXT
   ...
)
Run Code Online (Sandbox Code Playgroud)