[R] best way to handle database connections from within a package
Mark Sharp
msharp at txbiomed.org
Fri May 29 17:32:26 CEST 2015
I would simply separate the database connect and disconnect functions from the query functions.
Mark
R. Mark Sharp, Ph.D.
msharp at TxBiomed.org
> On May 28, 2015, at 12:18 PM, Luca Cerone <luca.cerone at gmail.com> wrote:
>
> Dear all,
> I am writing a package that is a collection of queries to be run
> against a postgresql database,
> so that the users do not have to worry about the structure of the database.
>
> In my package I import dbDriver, dbUnloadDriver, dbConnect,
> dbDisconnect from the package DBI
> and dbGetQuery from the package RPostgreSQL.
>
> All the function in a function in my package have the same structure:
>
> getFancyData <- function( from, to) {
> on.exit( dbDisconnect(con), add=TRUE)
> on.exit( dbUnloadDriver(drv), add=TRUE)
> drv <- dbDriver("PostgreSQL")
> con <- dbConnect(drv,
> user=pkguser,
> host=pkghost,
> password=pkgpassword,
> port = pkgport)
>
> query <- sprintf("select * from fancyTable where dt between '%s'
> and '%s'", from, to)
> res <- dbGetQuery(con,query)
> return(res)
> }
>
> The various access details are read from an encrypted profile that the
> user has to
> create when she installs the package.
>
> Such functions work perfectly fine, but I have to replicate a lot of
> times loading and unloading the driver and connecting and
> disconnecting from the database.
>
> I am wondering if there is a better way to do this job, like loading
> the driver and opening the connection only once when the package is
> loaded. However I have to make sure that
> if R crashes or the code where the function is called contains an
> error then the connection
> with the database is closed. How would you implement this?
>
>
> Also how would you write a functional that would at least allow me to
> avoid replicating
> the boilerplate code to load and unload the drivers?
>
> I am thinking something on the lines of:
>
> querybuild <- function(query, ....)
> on.exit( dbDisconnect(con), add=TRUE)
> on.exit( dbUnloadDriver(drv), add=TRUE)
> query <- sprintf(query, ... )
> res <- dbSendQuery(query)
> return(res)
> }
>
> and then define
>
> getFancyData <- function(from, to) querybuild("select * from
> fancyTable where dt between '%s' and '%s'", from, to)
>
> Do you see a better way?
>
> Thanks a lot in advance for your help and advice on this!
>
> Cheers,
> Luca
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list