Skip to main content

Introduction to SQLx

SQLx is a Rust library that provides type-safe database interactions without an ORM. Key features include:

  • Compile-time SQL verification: Checks your SQL queries at compile time
  • Native async support: Fully asynchronous database operations
  • Type safety: Maps database results to Rust types
  • No runtime reflection: Zero-cost abstractions for database access
  • Support for multiple databases: PostgreSQL, MySQL, SQLite, and more

For you as a .NET developer, SQLx is more like Dapper than Entity Framework, focusing on SQL queries rather than an ORM abstraction layer.

Setting Up PostgreSQL

In this module, you'll use Docker to run a local PostgreSQL instance:

# docker-compose.yml
services:
postgres:
image: postgres:17-alpine
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=mysupersecretlocalpassword
- POSTGRES_DB=users

You can start the database with:

docker compose up -d

Adding SQLx to Your Project

First, add SQLx to your Cargo.toml:

[dependencies]
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio"] }

The features you select determine which database drivers and runtime support are included.

Connecting to the Database

To connect to PostgreSQL, you'll need to:

  1. Get the database URL from an environment variable
  2. Create a connection pool
  3. Handle connection errors appropriately

Examine how this is implemented:

use std::env;
use sqlx::PgPool;
use crate::core::ApplicationError;

pub struct PostgresUsers {
db: PgPool,
}

impl PostgresUsers {
pub async fn new() -> Result<Self, ApplicationError> {
// Get database URL from environment variable
let db_url = &env::var("DATABASE_URL")
.map_err(|e| ApplicationError::DatabaseError(e.to_string()))?;

// Create connection pool
let database_pool = PgPool::connect(db_url)
.await
.map_err(|e| ApplicationError::DatabaseError(e.to_string()))?;

// Return new instance with connection pool
Ok(Self {
db: database_pool,
})
}
}