diff --git a/NAMESPACE b/NAMESPACE index e9cd49cd..63d11fe7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -115,6 +115,7 @@ export(src_bigquery) exportClasses(BigQueryConnection) exportClasses(BigQueryDriver) exportClasses(BigQueryResult) +exportMethods(dbAppendTable) exportMethods(dbBegin) exportMethods(dbBind) exportMethods(dbClearResult) diff --git a/NEWS.md b/NEWS.md index 2a9f2e75..5ea7bbb8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,11 @@ * `dbGetRowCount()` and `dbHasComplete()` now return correct values when you try to fetch more rows than actually exist (#501). +* `dbWriteTable()` now correct uses the `billing` value set in the + connection (#486). + +* Now supports `dbAppendTable()` (#539). + * `dbReadTable()`, `dbWriteTable()`, `dbExistsTable()`, `dbRemoveTable()`, and `dbListFields()` now all work with `DBI::Id()` (#537). diff --git a/R/dbi-connection.R b/R/dbi-connection.R index 47aba18e..cf82c892 100644 --- a/R/dbi-connection.R +++ b/R/dbi-connection.R @@ -1,13 +1,14 @@ #' @include dbi-driver.R NULL -BigQueryConnection <- - function(project, dataset, billing, +BigQueryConnection <- function(project, + dataset, + billing, page_size = 1e4, quiet = NA, use_legacy_sql = FALSE, bigint = c("integer", "integer64", "numeric", "character")) { - ret <- new("BigQueryConnection", + new("BigQueryConnection", project = project, dataset = dataset, billing = billing, @@ -16,7 +17,6 @@ BigQueryConnection <- use_legacy_sql = use_legacy_sql, bigint = match.arg(bigint) ) - ret } #' @rdname DBI @@ -180,9 +180,12 @@ dbWriteTable_bq <- function(conn, } tb <- as_bq_table(conn, name) - bq_table_upload(tb, value, + bq_table_upload( + tb, + value, create_disposition = create_disposition, write_disposition = write_disposition, + billing = conn@billing, ... ) invisible(TRUE) @@ -216,6 +219,27 @@ setMethod( dbWriteTable_bq ) +dbAppendTable_bq <- function(conn, name, value, ..., row.names = NULL) { + tb <- as_bq_table(conn, name) + + bq_table_upload(tb, value, + create_disposition = "CREATE_NEVER", + write_disposition = "WRITE_APPEND", + ... + ) + invisible(TRUE) +} + +#' @inheritParams DBI::dbAppendTable +#' @rdname DBI +#' @export +setMethod("dbAppendTable", c("BigQueryConnection", "character", "data.frame"), dbAppendTable_bq) + +#' @rdname DBI +#' @export +setMethod("dbAppendTable", c("BigQueryConnection", "Id", "data.frame"), dbAppendTable_bq) + + dbReadTable_bq <- function(conn, name, ...) { tb <- as_bq_table(conn, name) bq_table_download(tb, ...) diff --git a/man/DBI.Rd b/man/DBI.Rd index c14bbbad..74584468 100644 --- a/man/DBI.Rd +++ b/man/DBI.Rd @@ -23,6 +23,8 @@ \alias{dbDataType,BigQueryConnection-method} \alias{dbWriteTable,BigQueryConnection,character,data.frame-method} \alias{dbWriteTable,BigQueryConnection,Id,data.frame-method} +\alias{dbAppendTable,BigQueryConnection,character,data.frame-method} +\alias{dbAppendTable,BigQueryConnection,Id,data.frame-method} \alias{dbReadTable,BigQueryConnection,character-method} \alias{dbReadTable,BigQueryConnection,Id-method} \alias{dbListTables,BigQueryConnection-method} @@ -103,6 +105,10 @@ row.names = NA ) +\S4method{dbAppendTable}{BigQueryConnection,character,data.frame}(conn, name, value, ..., row.names = NULL) + +\S4method{dbAppendTable}{BigQueryConnection,Id,data.frame}(conn, name, value, ..., row.names = NULL) + \S4method{dbReadTable}{BigQueryConnection,character}(conn, name, ...) \S4method{dbReadTable}{BigQueryConnection,Id}(conn, name, ...) diff --git a/tests/testthat/test-dbi-connection.R b/tests/testthat/test-dbi-connection.R index ce3ab80e..3de2a6a5 100644 --- a/tests/testthat/test-dbi-connection.R +++ b/tests/testthat/test-dbi-connection.R @@ -74,9 +74,11 @@ test_that("can use DBI::Id()", { ds <- bq_test_dataset() con <- DBI::dbConnect(ds) - id <- DBI::Id(table = "mtcars") + df <- data.frame(x = 1:10) + id <- DBI::Id(table = "mytable") - expect_no_error(DBI::dbWriteTable(con, id, mtcars)) + expect_no_error(DBI::dbWriteTable(con, id, df)) + expect_no_error(DBI::dbAppendTable(con, id, df)) expect_no_error(DBI::dbReadTable(con, id)) expect_true(DBI::dbExistsTable(con, id)) expect_no_error(DBI::dbListFields(con, id)) @@ -91,8 +93,11 @@ test_that("can append to an existing dataset", { DBI::dbWriteTable(con, "df", df) DBI::dbWriteTable(con, "df", df, append = TRUE) + # Or with dbAppend + DBI::dbAppendTable(con, "df", df) + df2 <- DBI::dbReadTable(con, "df") - expect(nrow(df2), 2L) + expect(nrow(df2), 3L) }) test_that("dataset is optional", {