SQLx provides macros for compile-time syntactic and semantic verification of your SQL queries. This ensures your queries are valid and that the types match your Rust code.
sqlx::query!
Returns an anonymous record type where each SQL column is a field. Because the type is anonymous, you cannot name it in a function signature.
sqlx::query_as!
Identical to query!, but allows you to map the results into a named struct.
Requirements for Compile-time Verification
DATABASE_URL: This environment variable must be set at build time. It should point to a database with the same schema as your production database so SQLx can prepare the queries against it.- Offline Mode: To avoid requiring a live database during CI/CD or builds, you can use the
sqlx-cli to enable "offline mode," which caches query analysis results in a JSON file.
Performance Tip
To speed up incremental builds (like cargo check), add the following to your Cargo.toml to optimize the macro expansion:
[profile.dev.package.sqlx-macros]
opt-level = 3
// query! returns an anonymous record
let countries = sqlx::query!(
"SELECT country, COUNT(*) as count FROM users GROUP BY country WHERE organization = ?",
organization
)
.fetch_all(&pool)
.await?;
// countries[0].country
// query_as! maps to a named struct
struct Country { country: String, count: i64 }
let countries = sqlx::query_as!(Country,
"SELECT country, COUNT(*) as count FROM users GROUP BY country WHERE organization = ?",
organization
)
.fetch_all(&pool)
.await?;