sqlx-cloudflare-do
A Cloudflare Durable Objects driver for sqlx: a real
sqlx::Databaseover a Durable Object's SQL storage, so code written against sqlx's runtime API runs inside a Rust Durable Object.
[!NOTE] Pre-1.0. The API may still change between minor versions.
use ;
use ;
The class must be SQLite-backed -- new_sqlite_classes in wrangler.toml:
[[]]
= "USERS"
= "Users"
[[]]
= "v1"
= ["Users"]
Install
[]
= "0.1"
= { = "0.9", = false, = ["derive"] }
= "0.8"
# `#[durable_object]` expands to code that names it directly.
= "0.2"
| sqlx-cloudflare-do | sqlx | worker | Rust |
|---|---|---|---|
| 0.1 | 0.9 | 0.8 | 1.94+ |
The crate runs on wasm32-unknown-unknown, inside a Durable Object.
How it differs from D1
The database lives in the Durable Object, so a query never leaves the
process: sql.exec runs it before returning, and the driver reads every row
out on the spot. Each query's future finishes on its first poll. Types map
exactly as in sqlx-cloudflare-d1 -- the two share
one definition.
Limitations
- No
query!/query_as!macros. sqlx's macros only know its built-in drivers. The runtime API (sqlx::query,query_as,FromRow) works. - Transactions take a callback, not
begin().sql.execrejectsBEGINandSAVEPOINT, sobegin()fails.DoConnection::transactionruns a callback insideStorage::transactioninstead: a real transaction that reads its own writes and rolls back when the callback returnsErr. The callback must own what it uses ('static), and the object serves no other request until it ends, so keep it short -- nofetch()inside. - Batches.
DoConnection::execute_batchruns statements atomically, andDoConnection::fetch_batchstreams each statement's rows and result as well -- the shape of sqlc's:batch*queries. - No
sqlx::Pool. Nothing to pool: the connection is a handle to storage the object owns. Keep one in the object's struct. - Integers are limited to ±(2^53 − 1). Values cross as JavaScript
numbers, so a wider
i64is refused rather than silently rounded. Note that sqlx'sQueryBuilder::push_bindpanics on a refused value instead of returning the error. rows_affectedcomes fromchanges(). Like SQLite's own count, it covers the rows the statement itself inserted, updated or deleted, not those its triggers touched. A statement that wrote nothing reports 0 and nolast_insert_rowid.- No
sqlx::migrate!. Create the schema from the object's constructor. - No derived TEXT enums.
#[derive(sqlx::Type)]works for#[sqlx(transparent)]newtypes and#[repr(i32)]enums, but sqlx only generates string-backed enums for its built-in drivers. - No statement logging.
log_statementsis accepted and ignored.