Skip to contents

Readers (reports, analyses, downstream projects) should never block the pipeline that builds a database, and should still work while it runs. db_connect_read_only() opens the file read-only; if a writing process holds the lock, it opens the snapshot that the writer keeps up to date with db_refresh_snapshot(), and says how old it is.

Usage

db_connect_read_only(
  path,
  snapshot = TRUE,
  memory_limit = getOption("coRpusdb.memory_limit", "6GB"),
  threads = getOption("coRpusdb.threads")
)

Arguments

path

Character. Path of the .duckdb file (created if it does not exist and read_only is FALSE).

snapshot

Logical. Fall back on the snapshot when the file is locked.

memory_limit

Character or NULL. DuckDB memory limit (e.g. "6GB"); NULL keeps DuckDB's default. A warning is given when it exceeds the memory available (free_memory_gb()).

threads

Integer or NULL. Number of DuckDB threads (option coRpusdb.threads); NULL keeps DuckDB's default (all cores). Each thread holds its own buffers: fewer threads lower the memory peak a little, at a cost in speed (bench/results_memory.csv).

Value

A read-only DBI connection.

Details

DuckDB allows several read-only connections at once, but none while a process writes. The snapshot is a copy of the file taken between two write batches (see db_refresh_snapshot()): it lags behind the database, which is why its age is reported.

Examples

path <- tempfile(fileext = ".duckdb")
con <- db_connect(path)
#> duckdb is storing downloaded extensions and secrets under ~/.duckdb:
#> ℹ /home/agoutsmedt/.duckdb
#> This persists across sessions and is shared with the DuckDB CLI and other clients.
#> ℹ Run duckdb(shared_home = FALSE) to use a temporary directory instead.
#> ℹ See ?duckdb_storage for details and alternatives.
DBI::dbWriteTable(con, "document", data.frame(doc_id = "a:1"))
db_disconnect(con)

reader <- db_connect_read_only(path)
#> duckdb is storing downloaded extensions and secrets under ~/.duckdb:
#> ℹ /home/agoutsmedt/.duckdb
#> This persists across sessions and is shared with the DuckDB CLI and other clients.
#> ℹ Run duckdb(shared_home = FALSE) to use a temporary directory instead.
#> ℹ See ?duckdb_storage for details and alternatives.
DBI::dbListTables(reader)
#> [1] "document"
db_disconnect(reader)