Writing to specific schemas with RPostgreSQL
Asked Answered
P

3

31

I'm using RPostgreSQL to read and write data. Reading from any schema works perfectly, but I'm not able to write to non-public schemas. For example, the following code places a table in the public schema, with the name myschema.tablex

# write dataframe to postgres 
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host="localhost", user="postgres", password="zzzz", dbname="mydatabase", port="5436")
if(dbExistsTable(con,"myschema.tablex")) {
  dbRemoveTable(con,"myschema.vkt_tablex")}
dbWriteTable(con,"myschema.tablex", dataframe, row.names=F)

What I want to do, is to place the table tablex in the schema myschema. I've also tried to name the schema in the connection: dbname="mydatabase.myschema" and trying the argument schemaname which I saw referred to in an earlier bug.

None of these approaches work, so I'm wondering if there is another method that I can use.

Platitude answered 5/4, 2012 at 16:29 Comment(0)
M
6

The default schema where objects are created is defined by the search_path. One way would be to set it accordingly. For instance:

SET search_path = myschema, public;

I quote the manual:

When objects are created without specifying a particular target schema, they will be placed in the first schema listed in the search path. An error is reported if the search path is empty.

You can also make this the default for a role, so it is set automatically for every connection made by this role. More:

Morman answered 5/4, 2012 at 17:15 Comment(5)
Thanks @Erwin. If I have five schemas do I need to list them all in my preferred order, or just the one I want R to use?Platitude
@celenius: You don't have to list them all. The first schema in your search_path that your current role can access will be used for object creation. All of them will be searched in order for objects until they are found. Ohter schemas are invisible. Special rules apply for system schemas. Much like a search path in a file system. The manual tells it all.Morman
Note however that schema prefixing a tablename on create should work as well. i.e.: create schema test; create table test.abc (i int); \d test.abcMadura
@celenius: Like Scott said: the search_path only provides a default. Schema-qualifying names always overrules the default. Much like a fully qualified path in a file system.Morman
You could put @ErwinBrandstetter solution in a transaction, e.g., RPostgres::dbWithTransaction, so setting the search path is part of your transaction, afterwards it returns back to your ordinary search path.Gnosticize
M
57

Use this:

library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname = "db", host = "host", port = 5432,
                 user = "user", password = "pwd")
dbWriteTable(con, c("yourschema", "yourtable"), value = yourRdataframe)
dbDisconnect(con)

More details: https://stat.ethz.ch/pipermail/r-sig-db/2011q1/001043.html

Merilyn answered 17/8, 2012 at 7:19 Comment(3)
Also works with dbReadTable, should be the accepted answer.Carlin
This is not longer a valid solution, RPostgres 1.4.3Regorge
Using a vector dbWriteTable(con, c("yourschema", "yourtable"), value = yourRdataframe) actually is the only working solution, also in RPostgres 1.4.6, cannot confirm that "this is no longer valid". Id(), SQL() and all the other solutions always try to write into public schema...Analyse
M
6

The default schema where objects are created is defined by the search_path. One way would be to set it accordingly. For instance:

SET search_path = myschema, public;

I quote the manual:

When objects are created without specifying a particular target schema, they will be placed in the first schema listed in the search path. An error is reported if the search path is empty.

You can also make this the default for a role, so it is set automatically for every connection made by this role. More:

Morman answered 5/4, 2012 at 17:15 Comment(5)
Thanks @Erwin. If I have five schemas do I need to list them all in my preferred order, or just the one I want R to use?Platitude
@celenius: You don't have to list them all. The first schema in your search_path that your current role can access will be used for object creation. All of them will be searched in order for objects until they are found. Ohter schemas are invisible. Special rules apply for system schemas. Much like a search path in a file system. The manual tells it all.Morman
Note however that schema prefixing a tablename on create should work as well. i.e.: create schema test; create table test.abc (i int); \d test.abcMadura
@celenius: Like Scott said: the search_path only provides a default. Schema-qualifying names always overrules the default. Much like a fully qualified path in a file system.Morman
You could put @ErwinBrandstetter solution in a transaction, e.g., RPostgres::dbWithTransaction, so setting the search path is part of your transaction, afterwards it returns back to your ordinary search path.Gnosticize
C
3

In case a reader is using the newer package RPostgres to do this, the code to specify schemas is:

dbCreateTable(conn = con, name = Id(schema = "yourschema", table = "yourtable"), fields = yourRdataframe)

Copybook answered 10/11, 2020 at 3:52 Comment(1)
See help(Id) in the DBI package, the Id class refers "to a table nested in a hierarchy (e.g. within a schema)". This can also be used as the name argument in dbWriteTable.Siu

© 2022 - 2024 — McMap. All rights reserved.