better-duck-diesel is a third-party Diesel 2.3 backend for DuckDB. It plugs the
better-duck-core driver into Diesel’s typed query builder, so you connect, map a
schema with table!, and build INSERT/SELECT/UPDATE/DELETE queries as Rust — while still
reaching the DuckDB-specific SQL (operators, scalar functions, aggregates, types) that stock Diesel has
no equivalent for.
DuckDB itself is compiled and embedded through core, so there is no system install and no libduckdb to
link against.
What it is
DuckDbConnection is a full Diesel Connection + LoadConnection. That means:
conn.transaction(|c| …)andbegin_test_transactionwork — see Transactions.- Prepared-statement caching and instrumentation work.
r2d2pooling works — see Pooling.diesel migrationworks — the connection implementsMigrationConnection, see Schema & Migrations..inner()/.inner_mut()expose the underlying coreConnectionfor registering UDFs, loading extensions, and running core-only APIs — see Installation & Setup.
This crate’s default feature set is
["decimal"] only. Unlike better-duck-core, chrono is NOT on
by default here — turn it on for date/time column support. See Feature flags below.30-second quickstart
The two SQL surfaces
Diesel core already gives you the portable surface, and it works onDuckDbConnection with no extra
imports: =/</>, LIKE, count/sum/avg/min/max, .filter/.order/.limit, joins,
insert_into/update/delete, RETURNING, ON CONFLICT.
The DuckDB-only surface lives behind one import, brought in alongside Diesel’s prelude:
DuckExpressionMethods, DuckTextExpressionMethods)
plus a large library of typed free functions and aggregates — all emitting real DuckDB SQL, none
requiring sql_query. See the DSL overview for the map of this surface.
Spatial
ST_* functions are not in the dsl::* prelude — import them from
better_duck_diesel::spatial::* under feature = "spatial". See Spatial.Feature flags
Verified againstcrates/better-duck-diesel/Cargo.toml.
For the full project-wide feature picture, see feature flags.
When to use the ORM vs raw core
Reach forbetter-duck-diesel when you want a typed query builder, schema mapping, migrations, or
pooling over DuckDB.
Drop to better-duck-core whenever you need something below the ORM — the appender
for bulk insert, columnar chunks, async, Arrow/Polars interop, or raw parameter binding. Those are not
part of the Diesel surface. Because DuckDbConnection::inner_mut() hands you the core Connection, you
can mix both in the same program. See Choosing an API.
Sibling crates
better-duck-core
The raw Rust driver: connections, values, appender, columnar chunks, async.
UDF & derive macros
The
#[duckdb_*] UDF macros and FromRow/DuckEnum/DuckStruct derives.DuckDB SQL DSL
DuckDB-only operators, scalar functions, aggregates, and spatial.
Type mapping
Rust ↔ DuckDB type mapping and the
values::* binding newtypes.