-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to deal with pq__varchar
columns
#444
Comments
Thanks. Could you please provide a reproducible example? Please see https://reprex.tidyverse.org/ for guidance. |
Given any RPostgres connection to a postgresql database,
|
Ideally I would be able to treat the elements of |
The less than ideal solution that I eventually used for this situation was to parse the string representation of the array in R. But this only works easily because I have 1-D arrays with strings that do not have quote characters or commas in them. A better solution working directly from the x = dbGetQuery(con,"WITH a(v) AS (VALUES(ARRAY['a','b']::varchar[]),(ARRAY['abc','def','fgh']::varchar[])) SELECT * FROM a")
x$v_list = lapply(x$v,\(.) eval(parse(text=sub("[{]","c('",sub("[}]","')",gsub(",","','",.)))))) |
Reprex: con <- DBI::dbConnect(RPostgres::Postgres())
x <- DBI::dbGetQuery(con,"WITH a(v) AS (VALUES(ARRAY['a','b']::varchar[]),(ARRAY['abc','def','fgh']::varchar[])) SELECT * FROM a")
x
#> v
#> 1 {a,b}
#> 2 {abc,def,fgh}
class(x$v)
#> [1] "pq__varchar" Created on 2024-04-01 with reprex v2.1.0 @paleolimbot: Is there support for nested data in adbcpostgresql? |
It seems to! library(adbcdrivermanager)
con <- adbcpostgresql::adbcpostgresql() |>
adbc_database_init(uri = "postgresql://localhost:5432/postgres?user=postgres&password=password") |>
adbc_connection_init()
con |>
read_adbc(
"WITH a(v) AS (VALUES(ARRAY['a','b']::varchar[]),(ARRAY['abc','def','fgh']::varchar[])) SELECT * FROM a"
) |>
as.data.frame() |>
dplyr::pull()
#> <list_of<character>[2]>
#> [[1]]
#> [1] "a" "b"
#>
#> [[2]]
#> [1] "abc" "def" "fgh" Created on 2024-04-01 with reprex v2.1.0 I say this lightly, but I actually spent quite a bit of time getting this to work. It also works for postgres' "record" type, where it should give you back a nested data frame. There is a slight limitation on reading the array type...I believe multidimensional arrays will just be returned as a flat |
Thanks, this is wonderful! I suspect it will also work via adbi, https://adbi.r-dbi.org/. @dmkaplan2000: can you confirm? |
This brings up memories of my work bringing nested data to the duckdb R client. I do appreciate the effort! |
I tried getting this to work with con2 = dbConnect(adbi::adbi("adbcpostgresql"),uri="postgresql://localhost:5432/DBNAME?user=USER&password=PASSWORD") That worked without error, but when I tried to use the connection to execute a query I got: > dbGetQuery(con2,"WITH a(v) AS (VALUES(ARRAY['a','b']::varchar[]),(ARRAY['abc','def','fgh']::varchar[])) SELECT * FROM a")
Error in adbcdrivermanager::adbc_statement_get_parameter_schema(stmt) :
NOT_IMPLEMENTED Based on what I could find online, I tried reducing the URI to Do you know what I am doing wrong? The help on |
It's a moonshot, but can you try CC @nbenn. |
> con2 = dbConnect(adbi::adbi("adbcpostgresql"),uri="postgresql://localhost:5432")
> x=dbGetQuery(con2,"WITH a(v) AS (VALUES(ARRAY['a','b']::varchar[]),(ARRAY['abc','def','fgh']::varchar[])) SELECT * FROM a",immediate=TRUE)
> x$v
<list_of<character>[2]>
[[1]]
[1] "a" "b"
[[2]]
[1] "abc" "def" "fgh" So this query works with |
Hi, I recently just had to find a generic solution for converting 1-D Postgresql arrays in a # Generate data
con <- DBI::dbConnect(RPostgres::Postgres())
q = "WITH a(v) AS (VALUES(ARRAY['''a''','b']::varchar[]),(ARRAY['abc, def','the \"big\" one','fgh']::varchar[])) SELECT * FROM a"
x <- DBI::dbGetQuery(con,q)
# Function that does the work on individual varchar arrays imported into R
pq_varchar_array_to_char = function(x) {
x |>
gsub("^[{]|[}]$", "", x = _) |>
gsub("[\\][\"]","%myspecialquote%",x = _) |>
scan(text = _, quote = '"', what = "", sep = ",", quiet = TRUE) |>
gsub("%myspecialquote%","\"",x = _)
}
# Apply function to each element of column of x
## Non-tidyverse version
out <- transform(x, v = lapply(v, pq_varchar_array_to_char))
## Tidyverse version
library(tidyverse)
out2 <- mutate(x, v = lapply(v, pq_varchar_array_to_char)) Perhaps some version of This function could also be extended to work with various types of Postgresql arrays (for example, with a generic This function could probably be extended to the case of N-D arrays, but that is not my use case for the time being... |
Thanks. Does the |
No, I don't think > con <- DBI::dbConnect(RPostgres::Postgres())
> q = "WITH a(v) AS (VALUES(ARRAY['''a''','b']::varchar[]),(ARRAY['abc, def','the \"big\" one','fgh']::varchar[])) SELECT * FROM a"
> x <- DBI::dbGetQuery(con,q)
> x
v
1 {'a',b}
2 {"abc, def","the \\"big\\" one",fgh}
> x$v[2]
[1] "{\"abc, def\",\"the \\\"big\\\" one\",fgh}"
> class(x)
[1] "data.frame"
> class(x$v)
[1] "pq__varchar"
> class(x$v[2])
[1] "character" Is that what you wanted? |
Yes, thanks. Maybe we could leverage the PostgreSQL |
I have some queries that return columns of type
pq__varchar
. I was wondering if there was some simple way to convert these data into a more R friendly format inside R?Thanks,
David
The text was updated successfully, but these errors were encountered: