By default, every call toDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nimdeveloper/better-duck/llms.txt
Use this file to discover all available pages before exploring further.
Connection::open_in_memory() creates a completely separate DuckDB database. Two connections opened this way cannot see each other’s tables or data — they are fully isolated. When you need multiple connections to observe the same data (including in-memory data), you need the Database handle: open one Database, then call db.connect() to derive as many connections as you need. All of them share the single underlying DuckDB database instance.
The Database Handle
Database is a thin, cheap Arc-backed wrapper around the raw DuckDB database handle (duckdb_database). Cloning it is an atomic reference-count bump; no new DuckDB objects are created. The underlying database is destroyed only when the last Arc referencing it is dropped — which means it outlives individual connections, and connections can be dropped and reopened freely without losing data.
Database::open(path)
Open or create an on-disk DuckDB database
Database::open_in_memory()
Create an in-memory database shared by all connections derived from it
db.connect()
Spawn a new
Connection attached to this databaseMethod signatures
| Method | Description |
|---|---|
Database::open<P: AsRef<Path>>(path: P) -> Result<Database> | Open (or create) an on-disk database |
Database::open_with_flags<P: AsRef<Path>>(path: P, config: Config) -> Result<Database> | Same, with extra DuckDB config |
Database::open_in_memory() -> Result<Database> | Create a shared in-memory database |
Database::open_in_memory_with_flags(config: Config) -> Result<Database> | Same, with extra DuckDB config |
db.connect() -> Result<Connection> | Spawn a new connection to this database |
Shared In-Memory Database
Open oneDatabase and call db.connect() twice — both connections see the same tables and rows:
Database — including clones of the Database handle itself — share one consistent view of the data. This applies whether the database is in-memory or file-based.
Independent In-Memory Connections
For contrast, opening two connections withConnection::open_in_memory() gives each its own isolated database:
Connection::open_in_memory() when you want complete isolation — for example, in a test suite where each test should start from a clean slate. Use Database::open_in_memory() when multiple actors need to share state.
Getting a Database from a Connection
You don’t always start from aDatabase. If you already have a Connection, call conn.database() to retrieve the Arc-backed Database handle. From there, use db.connect() to spawn sibling connections that share the same underlying database.
| Method | Description |
|---|---|
conn.database() -> Database | Return the Arc-backed handle for the database backing this connection |
Connection Lifetime vs. Database Lifetime
BecauseDatabase is Arc-backed, the underlying DuckDB database instance lives as long as there is at least one Database handle or Connection referencing it — whichever outlives the other. You can safely drop the Database you used to open the database while connections derived from it are still in use:
Thread Safety
Database is Send + Sync. You can clone a Database handle and share the clone across threads, or move it into a tokio::spawn task, without any additional synchronization: