SeaORM
SeaORM é um ORM assíncrono construído sobre sqlx - consultas dinâmicas, relações e codegen para backends do tipo serviço em Rust.
Receita
Cartão de referência rápida - pronto para copiar e colar.
use sea_orm::{entity::*, query::*, Database};
let db = Database::connect(&database_url).await?;
let users = User::find()
.filter(user::Column::Active.eq(true))
.all(&db)
.await?;Quando usar isso: Você quer a ergonomia de um ORM assíncrono, helpers de relação e codegen sem o modelo síncrono do Diesel.
Exemplo Funcional
use sea_orm::{entity::prelude::*, Database, Set};
mod item {
use super::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "items")]
pub struct Model { #[sea_orm(primary_key)] pub id: i64, pub name: String }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
}
use item::{self, Entity as Item};
#[tokio::main]
async fn main() -> Result<(), sea_orm::DbErr> {
let db = Database::connect(&std::env::var("DATABASE_URL").unwrap()).await?;
let am = item::ActiveModel { name: Set("widget".to_string()), ..Default::default() };
let model = am.insert(&db).await?;
let all = Item::find().all(&db).await?;
println!("{:?} {:?}", model, all);
Ok(())
}O que isto demonstra:
- Codegen
DeriveEntityModelpara mapeamento de tabelas. ActiveModelpara inserções com camposSet.- API de consulta fluente
Entity::find(). - Conexão
Databaseassíncrona em todo o código.
Análise Detalhada
Como Funciona
- SeaORM usa drivers sqlx internamente.
sea-orm-cligera entidades a partir de migrações ou introspecção de banco de dados.- Relações expressam joins e helpers de carregamento antecipado (eager loading).
SeaORM vs sqlx Raw
| Tópico | SeaORM | sqlx |
|---|---|---|
| Consultas | Builder + entidades | Strings SQL |
| Relações | Integrado | Joins manuais |
| Filtros dinâmicos | Forte suporte | Construção manual de SQL |
| Controle | Menos SQL visível | SQL completo |
Notas de Rust
// Paginação
let page = Item::find().paginate(&db, 50);
let models = page.fetch_page(0).await?;Armadilhas
- Vazamento do ORM para handlers - Retornar
ActiveModelde APIs. Correção: Mapear para DTOs na fronteira. - N+1 implícito -
load_relatedem loops. Correção: Padrões defind_with_relatedcom carregamento antecipado. - Pilha dupla de migração - Confusão entre migrações SeaORM e sqlx migrate. Correção: Escolha uma ferramenta de migração por repositório.
- Codegen pesado - Regeneração de entidade após mudança de esquema é obrigatória. Correção: Passo de CI
sea-orm-cli generate. - SQL de relatórios complexos - ORM tem dificuldade com consultas analíticas. Correção: sqlx raw apenas para relatórios.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| sqlx | Controle SQL, stack mais simples | API de relação rica necessária |
| Diesel | Query builder em tempo de compilação | Assíncrono nativo necessário |
tokio-postgres | Abstração mínima | Serviços com muitas operações CRUD |
FAQs
Quais bancos de dados?
PostgreSQL, MySQL, SQLite via backends sqlx.
Transações?
db.begin().await? retorna um handle de transação para operações de entidade.
Soft deletes?
Padrões de filtro globais na coluna deleted_at em consultas de entidade.
Campos JSON?
Tipo de coluna Json com tipos serde.
Testes?
SQLite em memória Database::connect("sqlite::memory:").
Integração com Axum?
Armazene DatabaseConnection em AppState - clone barato.
Inserções em lote?
Entity::insert_many(active_models).exec(&db).
Ferramenta de migração?
Crate sea-orm-migration com arquivos de migração Rust.
Performance?
Profile o SQL gerado - o ORM pode emitir consultas subótimas.
Quando não usar SeaORM?
SQL customizado pesado, consultas de data warehouse, ou micro-CRUD simples apenas com sqlx.
Relacionado
- sqlx - Camada de driver subjacente
- Diesel - Alternativa de ORM síncrono
- Migrations - Evolução do esquema
- Padrões de Consulta e N+1 - Carregamento de relações
- Pool de Conexões - Configuração do pool
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.