| Crates.io | atmosphere |
| lib.rs | atmosphere |
| version | 0.4.1 |
| created_at | 2023-07-01 14:20:31.609883+00 |
| updated_at | 2025-10-29 15:15:55.742545+00 |
| description | A lightweight SQL framework for sustainable database reliant systems |
| homepage | |
| repository | https://github.com/helsing-ai/atmosphere |
| max_upload_size | |
| id | 905546 |
| size | 2,018,876 |
Atmosphere is a lightweight SQL framework designed for sustainable, database-reliant systems. It leverages Rust's powerful type and macro systems to derive SQL schemas from your rust struct definitions into an advanced trait system.
atmosphere::testinguse atmosphere::prelude::*;
#[table(schema = "public", name = "user")]
struct User {
#[sql(pk)]
id: i32,
name: String,
#[sql(unique)]
email: String,
}
#[table(schema = "public", name = "post")]
struct Post {
#[sql(pk)]
id: i32,
#[sql(fk -> User, rename = "author_id")]
author: i32,
#[sql(unique)]
title: String,
}
#[tokio::main]
async fn main() -> sqlx::Result<()> {
let pool = atmosphere::Pool::connect(&std::env::var("DATABASE_URL").unwrap()).await?;
// CRUD operations
let user = User { id: 0, name: "demo".to_owned(), email: "some@email.com".to_owned(), };
user.save(&pool).await?;
user.delete(&pool).await?;
user.create(&pool).await?;
// Field Queries
assert_eq!(
User::read(&pool, &0).await?,
User::find_by_email(&pool, "some@email.com").await?.unwrap()
);
// Relationships
Post { id: 0, author: 0, title: "test".to_owned() }
.save(&pool)
.await?;
Post::find_by_author(&pool, &0).await?;
Post::delete_by_author(&pool, &0).await?;
// Inter-Table Operations
Post { id: 1, author: 0, title: "test1".to_owned() }
.author(&pool).await?;
user.posts(&pool).await?;
user.delete_posts(&pool).await?;
Ok(())
}
Atmosphere introspects the User and Post structs at compile time and
generates const available type information about the schema into the Table
trait.
Table, Column, Relation ..)#[sql(pk)], #[sql(fk -> Model)] and so on)#[table])atmosphere::hooksmiettevalidator support#[virtual = "<sql>"])#[query])Generate GraphQL + HTTP Servers?
Generate Graphs
Given a struct Model that derives its atmosphere schema using #[table]:
use atmosphere::prelude::*;
#[table(schema = "public", name = "model")]
struct Model {
#[sql(pk)]
id: i32,
a: String,
#[sql(unique)]
b: String,
}
Atmosphere is able to derive and generate the following queries:
atmosphere::CreateModel::createatmosphere::ReadModel::read: read a Model by its primary key, returning a Model.Model::find: find a Model by its primary key, returning an Option<Model>.Model::read_all: read all Models, returning a Vec<Model>.Model::reloadatmosphere::UpdateModel::updateModel::upsertatmosphere::DeleteModel::deleteModel::delete_byEach struct field that is marked with #[sql(unique)] becomes queryable.
In the above example b was marked as unique so atmosphere implements:
Model::find_by_b: find a Model by its b field, returning an Option<Model>.Model::delete_by_b: delete a Model by its b field.Given that a model contains fields are marked as a foreign key / point to
another atmosphere::Table atmosphere – for example:
#[table(schema = "public", name = "submodel")]
struct Submodel {
#[sql(pk)]
id: i32,
#[sql(fk -> Model)]
super: i32,
}
Atmosphere is able to generate utility queries to move across Table boundaries:
Model::submodelsModel::delete_submodelsSubmodel::modelSubmodel::find_by_modelSubmodel::delete_by_modelNote that the function names contain
modelandsubmodel– they are derived from the respective struct names.
Several databases support a JSON (and often JSONB) type, for which sqlx has native support through #[sqlx(json)] and #[sqlx(json(nullable))].
Since atmosphere only needs to know whether the column is JSON and to stay forward-compatible with future changes to sqlx's attribute, we use the following syntax:
#[table(schema = "public", name = "submodel")]
struct Submodel {
#[sql(pk)]
id: i32,
#[sql(json)]
#[sqlx(json)]
data: HashMap<String, u64>,
#[sql(json)]
#[sqlx(json(nullable))]
optional_data: Option<HashMap<String, String>>,
}
You can also manually handle the JSON support using the following (it will mean accessing the inner type through .as_ref() or .0):
use sqlx::types::Json;
#[table(schema = "public", name = "submodel")]
struct Submodel {
#[sql(pk)]
id: i32,
data: Json<HashMap<String, u64>>,
optional_data: Option<Json<HashMap<String, String>>>,
}
We welcome contributions! Please see our contribution guidelines for more details.
Atmosphere is licensed under Apache 2.0.