ORM para Rust: comparação e exemplos
O ecossistema Rust oferece várias soluções poderosas para trabalhar com bancos de dados. Neste artigo, compararemos três ferramentas populares do tipo ORM: Diesel, SeaORM e SQLx. Cada uma tem sua própria filosofia e área de aplicação. Vamos analisar suas características, desempenho e fornecer exemplos práticos.
1. Diesel — ORM clássico com segurança de tipos
Diesel é o ORM mais maduro para Rust, construído com base no princípio de "segurança de tipos em tempo de compilação". Ele exige a descrição explícita do esquema por meio de migrações e gera estruturas estritamente tipadas.
Características:
- A compilação verifica a correção das consultas (erros de SQL — na fase de compilação)
- Suporte a PostgreSQL, MySQL, SQLite
- Mecanismo síncrono (para assincronia, é necessário
diesel-async) - DSL próprio para construção de consultas
Exemplo de código (Diesel + PostgreSQL):
// models.rsuse diesel::prelude::*;
#[derive(Queryable, Selectable)]#[diesel(table_name = crate::schema::users)]#[diesel(check_for_backend(diesel::pg::Pg))]pub struct User { pub id: i32, pub name: String, pub email: String,}
// main.rsuse diesel::prelude::*;use diesel::pg::PgConnection;
fn get_user(conn: &mut PgConnection, user_id: i32) -> Option<User> { use crate::schema::users::dsl::*; users.filter(id.eq(user_id)) .first::<User>(conn) .ok()}Quando escolher: para projetos onde a segurança das consultas em tempo de compilação é crítica e você está disposto a seguir um esquema rigoroso.
2. SeaORM — ORM assíncrono com abordagem ActiveRecord
SeaORM é um ORM assíncrono moderno, inspirado no Ruby on Rails. Suporta tanto code-first quanto geração de entidades a partir de um BD existente.
Características:
- Assincronia total (Tokio, async-std)
- Suporte a PostgreSQL, MySQL, SQLite e também CockroachDB
- Migrações, relacionamentos (has_many, belongs_to), paginação
- Gerador de código
sea-orm-cli
Exemplo de código (SeaORM + PostgreSQL):
use sea_orm::*;use entity::user;
async fn find_user(db: &DatabaseConnection, user_id: i32) -> Result<Option<user::Model>, DbErr> { user::Entity::find_by_id(user_id) .one(db) .await}
// Usoasync fn example() { let db = Database::connect("postgres://user:pass@localhost/db").await.unwrap(); if let Some(user) = find_user(&db, 42).await.unwrap() { println!("User: {} ({})", user.name, user.email); }}Quando escolher: para aplicações web assíncronas (Actix, Axum), onde é necessário desenvolvimento ativo e funcionalidades ricas "prontas para uso".
3. SQLx — "quase ORM" com máxima flexibilidade
SQLx não é exatamente um ORM, mas sim um cliente SQL assíncrono com verificação de consultas. Ele permite escrever SQL puro, mas verifica sua correção em tempo de compilação.
Características:
- Verificação de consultas em tempo de compilação (através da macro
sqlx::query!) - Assincronia total
- Suporte a PostgreSQL, MySQL, SQLite, MSSQL
- Suporte a JSON, migrações, pool de conexões
Exemplo de código (SQLx + PostgreSQL):
use sqlx::PgPool;
#[derive(sqlx::FromRow)]struct User { id: i32, name: String, email: String,}
async fn get_user(pool: &PgPool, user_id: i32) -> Result<Option<User>, sqlx::Error> { sqlx::query_as::<_, User>("SELECT id, name, email FROM users WHERE id = $1") .bind(user_id) .fetch_optional(pool) .await}Quando escolher: se você prefere escrever SQL
Também na biblioteca
Geração de relatórios PDF em Java com iText e Apache PDFBox
UUID em JavaScript (Node.js): guia completo com exemplos práticos
Integração de métricas Prometheus em aplicações Java: biblioteca simpleclient
Scrutor para C# (.NET): guia completo com exemplos práticos
Armadillo C++: Guia completo com exemplos práticos