Overview
SQLx provides:- Async queries — Non-blocking database access compatible with the Tokio runtime
- Compile-time query checking — Optional
query!macro that verifies SQL at build time - Connection pooling — Reusable database connections via
sqlx::PgPoolOptions - Type-safe models —
#[derive(FromRow)]for mapping query results to Rust structs
Configuration
The database connection pool is configured insrc/utils/database.rs:
Connection pool settings
| Setting | Value | Purpose |
|---|---|---|
max_connections | 10 | Maximum concurrent connections |
min_connections | 0 | Minimum idle connections |
max_lifetime | 20 minutes | Connection recycling interval |
idle_timeout | 60 seconds | Idle connection cleanup |
test_before_acquire | true | Validate connections before use |
Migration ownership
The bot service runs migrations from its ownmigrations/ directory during startup. The current bot-owned migration creates settings tables in the annie_mei schema:
annie_mei.user_settingsfor per-member preferencesannie_mei.guild_settingsfor Discord server preferences
migrations/. The auth service runs them on startup with sqlx::migrate!("./migrations").
Bot repo migrations
Auth repo schema migrations
Creating auth schema migrations
Create new OAuth schema migrations from the auth service repo:Coordinate schema changes with the bot repo when you add, rename, or remove columns that the bot reads or deletes.
Running migrations
The auth service runs migrations during startup. To run them manually from the auth service repo:Querying with SQLx
The bot reads from the auth-service-ownedoauth_credentials table using sqlx::query_as with FromRow structs:
src/models/db/oauth_credential.rs
FromRow— Derivessqlx::FromRowto map query columns to struct fields by namequery_as— Executes raw SQL and maps results to a typed structfetch_optional— ReturnsOk(None)when no row matches instead of an error- Async — All queries are
asyncand compatible with the Tokio runtime - Pool reference — Pass
&DbPoolrather than acquiring a connection manually
Batch lookups
Theget_by_discord_ids method queries multiple users at once for guild member status:
Writing data
The/unregister command demonstrates writing data using SQLx transactions:
Accessing the pool in commands
The connection pool is stored in Serenity’sTypeMap and accessed in command handlers:
Setup
Install SQLx CLI for auth schema work
Create the database
Run auth migrations manually
Check migration status
Troubleshooting
Can't connect to database
Can't connect to database
Verify environment variables:Test connection:
Migration failures
Migration failures
For bot startup migration failures, check the For auth service OAuth migration failures, check migration state from the auth repo:For persistent auth issues, inspect the auth service
cargo run startup output for the failing SQLx migration and verify the database user can create the annie_mei schema and tables.Inspect the bot migration table from the bot repo database connection:_sqlx_migrations table directly.Pool exhaustion
Pool exhaustion
If you see connection timeout errors:
- Check
max_connectionsincreate_pool()(default: 10) - Ensure PostgreSQL’s
max_connectionsis higher than the pool limit - Look for long-running queries or missing
awaitpoints
Next Steps
Architecture
Understand how database fits in the architecture
Adding Commands
Use database connections in commands
SQLx Documentation
Official SQLx repository and docs
