## ----include = FALSE---------------------------------------------------------- # Evaluate chunks only where the ducklake DuckDB extension is already # installed. The probe never downloads anything, so building this vignette # needs no network access. ducklake_available <- ducklake::ducklake_extension_available() knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = ducklake_available ) # Use a unique temp directory for this vignette to avoid conflicts during R CMD check vignette_temp_dir <- file.path(tempdir(), "data_inlining_vignette") dir.create(vignette_temp_dir, showWarnings = FALSE, recursive = TRUE) knitr::opts_knit$set(root.dir = vignette_temp_dir) ## ----setup, message = FALSE--------------------------------------------------- library(ducklake) library(dplyr) ## ----create-lake, message = FALSE--------------------------------------------- # The ducklake extension only needs installing once per machine: # install_ducklake() attach_ducklake("sensor_lake", lake_path = vignette_temp_dir) ## ----create-table------------------------------------------------------------- readings <- data.frame( sensor_id = 1:3, temperature = c(21.5, 22.1, 21.8), ts = as.POSIXct( c("2025-03-27 10:00:00", "2025-03-27 10:00:10", "2025-03-27 10:00:20"), tz = "UTC" ) ) with_transaction( create_table(readings, "readings"), author = "Sensor Team", commit_message = "Initial sensor readings" ) ## ----verify-no-parquet-------------------------------------------------------- conn <- get_ducklake_connection() DBI::dbGetQuery( conn, sprintf("SELECT count(*) AS parquet_files FROM glob('%s/**/*.parquet');", vignette_temp_dir) ) ## ----query-inline------------------------------------------------------------- get_ducklake_table("readings") |> collect() ## ----small-update------------------------------------------------------------- # Add a calibrated temperature column with_transaction( get_ducklake_table("readings") |> mutate(temp_calibrated = temperature - 0.3) |> replace_table("readings"), author = "Sensor Team", commit_message = "Add calibrated temperature" ) get_ducklake_table("readings") |> collect() ## ----small-delete------------------------------------------------------------- # Remove sensor 2's reading with_transaction( get_ducklake_table("readings") |> filter(sensor_id != 2) |> replace_table("readings"), author = "Sensor Team", commit_message = "Remove faulty sensor 2 reading" ) get_ducklake_table("readings") |> collect() ## ----large-insert------------------------------------------------------------- # 50 rows — well above the default threshold of 10 large_batch <- data.frame( sensor_id = 101:150, temperature = rnorm(50, mean = 22, sd = 1), ts = seq(as.POSIXct("2025-03-28 00:00:00", tz = "UTC"), by = "10 sec", length.out = 50), temp_calibrated = rnorm(50, mean = 21.7, sd = 1) ) with_transaction( create_table(large_batch, "readings_bulk"), author = "Sensor Team", commit_message = "Bulk sensor upload" ) # This table has a Parquet file DBI::dbGetQuery( conn, sprintf("SELECT count(*) AS parquet_files FROM glob('%s/**/*.parquet');", vignette_temp_dir) ) ## ----set-global--------------------------------------------------------------- # Increase the threshold for a streaming workload set_inlining_row_limit(50) get_inlining_row_limit() ## ----attach-limit, eval = FALSE----------------------------------------------- # attach_ducklake( # "streaming_lake", # lake_path = "/data/streaming", # data_inlining_row_limit = 100 # ) ## ----table-limit, eval = FALSE------------------------------------------------ # set_inlining_row_limit(100, table_name = "readings") ## ----disable-inline----------------------------------------------------------- set_inlining_row_limit(0) # All writes now go directly to Parquet, even single rows ## ----restore-default, include = FALSE----------------------------------------- # Restore default for the rest of the vignette set_inlining_row_limit(10) ## ----flush-------------------------------------------------------------------- flush_result <- flush_inlined_data() flush_result ## ----post-flush--------------------------------------------------------------- get_ducklake_table("readings") |> collect() ## ----flush-table, eval = FALSE------------------------------------------------ # flush_inlined_data(table_name = "readings") ## ----checkpoint, eval = ducklake_available && .Platform$OS.type != "windows"---- checkpoint_ducklake() ## ----time-travel-setup-------------------------------------------------------- # Check available snapshots snapshots <- list_table_snapshots("readings") snapshots ## ----time-travel-query-------------------------------------------------------- # Query an earlier version if (nrow(snapshots) > 0) { first_version <- snapshots$snapshot_id[1] get_ducklake_table_version("readings", first_version) |> collect() } ## ----cleanup, include = FALSE------------------------------------------------- try(detach_ducklake("sensor_lake"), silent = TRUE)