What is SQLx and why is it needed?
\n\nSQLx is an asynchronous, pure Rust library for working with databases that implements the "SQL without ORM" approach. Unlike ORM solutions such as Diesel or SeaORM, SQLx does not hide SQL queries behind abstractions, but allows you to write pure SQL code while providing full type safety at compile time.
\n\nMain advantages of SQLx:
\n- \n
- Type safety at compile time — SQLx checks your SQL queries against the database schema directly during project build. \n
- Asynchronous out of the box — the library fully supports async/await, which is ideal for high-load web applications. \n
- Support for multiple DBMS — PostgreSQL, MySQL, SQLite, and MSSQL. \n
- No magic — you write regular SQL, and the library only helps safely pass parameters and retrieve results. \n
- Migrations — built-in system for managing database schema migrations. \n
SQLx is ideal for projects where full control over queries, performance, and type safety are important, but you don't want to learn complex ORM DSLs (domain-specific languages).
\n\nInstallation
\n\nSQLx is installed via the Cargo package manager. Add the dependency to the Cargo.toml file:
[dependencies]\nsqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres"] }\ntokio = { version = "1", features = ["full"] }\nanyhow = "1.0"\n\nDepending on the database you are using, select the appropriate feature flag:
\n- \n
postgres— for PostgreSQL \n mysql— for MySQL \n sqlite— for SQLite \n mssql— for Microsoft SQL Server \n
For the runtime, you can choose runtime-tokio-rustls (recommended) or runtime-async-std-rustls.
Quick Start
\n\nLet's create a simple application that connects to PostgreSQL and executes a query:
\n\nuse sqlx::postgres::PgPoolOptions;\nuse anyhow::Result;\n\n#[tokio::main]\nasync fn main() -> Result<()> {\n // Create a connection pool\n let pool = PgPoolOptions::new()\n .max_connections(5)\n .connect("postgres://user:password@localhost/mydb")\n .await?;\n\n // Execute a simple query\n let row: (i64,) = sqlx::query_as("SELECT $1::bigint")\n .bind(42_i64)\n .fetch_one(&pool)\n .await?;\n\n println!("Result: {}", row.0);\n\n Ok(())\n}\n\nThis code creates a pool of 5 connections to the database, executes a query with a parameter, and prints the result.
\n\nMain SQLx Methods and Functions
\n\n1. sqlx::query
\nWhat it does: Creates a new SQL query with the ability to bind parameters. This is the basic building block for all operations.
\nParameters:
\n- \n
sql: &str— SQL query string with placeholders ($1, $2 for PostgreSQL; ? for MySQL/SQLite) \n
Example:
\nuse sqlx::query;\n\nlet query = sqlx::query("SELECT * FROM users WHERE id = $1 AND active = $2")\n .bind(1)\n .bind(true);\n\n2. .bind()
\nWhat it does: Binds a value to a query parameter. The order of calls corresponds to the order of placeholders in the SQL.
\nParameters:
\n- \n
value: impl Encode + Type<DB>— any value that can be encoded for the DB (i32, String, bool, Option, etc.) \n
Example:
\nlet user_id: i32 = 42;\nlet user_name: &str = "Alice";\n\nsqlx::query("INSERT INTO users (id, name) VALUES ($1, $2)")\n .bind(user_id)\n .bind(user_name)\n .execute(&p