Writes data to a DuckLake table. Supports two input types:
data.frame/tibble: Data is transferred from R to DuckDB. Use this when you have data in R memory (e.g., from CSV, API, or computation).
Lazy dbplyr table: Data stays in DuckDB - no R memory used. Use this for
transformations within the lake (e.g., cleaning, aggregating). The dplyr
pipeline is converted to SQL and executed as CREATE TABLE AS SELECT or
INSERT INTO ... SELECT.
Usage
db_write(
data,
schema = "main",
table,
mode = c("overwrite", "append"),
col_types = NULL,
partition_by = NULL,
bucket_by = NULL,
sort_by = NULL,
inline = FALSE,
commit_author = NULL,
commit_message = NULL
)Arguments
- data
A data.frame, tibble, or lazy dbplyr table (from
db_read()ortbl()). Lazy tables enable zero-copy transformations within DuckDB.- schema
Schema name (default "main")
- table
Table name
- mode
"overwrite" or "append"
- col_types
Optional named list or character vector specifying column types. Only applies to data.frame input (ignored for lazy tables). Overrides automatic type inference for stricter schema control. Format:
list(id = "BIGINT", value = "DECIMAL(10,2)")orc(id = "BIGINT", value = "DECIMAL(10,2)"). Supported types: INTEGER, BIGINT, DOUBLE, DECIMAL(p,s), VARCHAR, BOOLEAN, DATE, TIMESTAMP, INTERVAL, BLOB, GEOMETRY, etc.- partition_by
Optional character vector of column names to partition by. Only valid for mode = "overwrite". On overwrite, if not specified, existing partitioning is preserved.
- bucket_by
Optional list specifying bucket partitioning for high-cardinality columns. Format:
list(column = "col_name", buckets = 16). Uses Iceberg-compatible Murmur3 hashing. Only valid for mode = "overwrite".- sort_by
Optional character vector of column names to sort/cluster by. Improves query performance for range scans and filters on these columns. Only valid for mode = "overwrite".
- inline
Deprecated. DuckLake automatically inlines small writes based on the
data_inlining_row_limitthreshold (default 10 rows). Usedb_set_inline_threshold()to adjust the threshold for a table.Optional author for DuckLake commit metadata
- commit_message
Optional message for DuckLake commit metadata
See also
db_flush_inlined() to flush inlined data, db_set_clustering() to
change clustering on existing tables, db_recluster() to re-sort data
Examples
if (FALSE) { # \dontrun{
# ==== data.frame approach (data passes through R) ====
# Basic overwrite
db_write(my_data, table = "imports")
# With schema
db_write(my_data, schema = "trade", table = "imports")
# With partitioning (overwrite mode only)
db_write(my_data, schema = "trade", table = "imports",
partition_by = c("year", "month"))
# With explicit column types for stricter schema control
db_write(my_data, table = "financials",
col_types = list(id = "BIGINT", amount = "DECIMAL(12,2)"))
# ==== Lazy table approach (zero-copy, stays in DuckDB) ====
# Transform and write without collect() - no R memory used
db_read(table = "raw_imports") |>
filter(year == 2024) |>
mutate(value_eur = value * exchange_rate) |>
group_by(country, month) |>
summarise(total = sum(value_eur), .groups = "drop") |>
db_write(schema = "clean", table = "monthly_summary")
# Append transformed data
db_read(table = "staging") |>
filter(!is.na(id)) |>
db_write(table = "production", mode = "append")
# Join tables and write result
orders <- db_read(table = "orders")
products <- db_read(table = "products")
orders |>
left_join(products, by = "product_id") |>
select(order_id, product_name, quantity, price) |>
db_write(table = "order_details")
# ==== Other options ====
# DuckLake automatically inlines small writes (< threshold rows)
# Use db_set_inline_threshold() to adjust the threshold
db_write(batch, table = "events", mode = "append")
# With commit metadata
db_write(my_data, table = "imports", mode = "append",
commit_author = "jsmith",
commit_message = "Added Q3 data")
} # }