Trabalhando com bancos de dados em Rust: PostgreSQL e MongoDB para iniciantes
\n\nRust é uma linguagem de programação de sistemas moderna que está ganhando popularidade devido ao seu desempenho e segurança. Mas como trabalhar com bancos de dados em Rust? Neste artigo, abordaremos a conexão e a execução de operações básicas com dois SGBDs populares: o relacional PostgreSQL e o orientado a documentos MongoDB. O material é voltado para desenvolvedores iniciantes familiarizados com os fundamentos do Rust.
\n\nPor que Rust e bancos de dados são uma boa combinação?
\n\nRust oferece um sistema de tipos rigoroso e garantias de segurança de memória, o que é especialmente valioso ao trabalhar com dados. Erros de acesso à memória, típicos em C/C++, são eliminados em tempo de compilação. Além disso, o ecossistema Rust inclui bibliotecas maduras para interagir com bancos de dados: diesel para PostgreSQL e o driver oficial para MongoDB.
Neste artigo, aprenderemos:
\n- \n
- Conectar-se ao PostgreSQL e MongoDB a partir do Rust \n
- Executar operações CRUD (criação, leitura, atualização, exclusão) \n
- Trabalhar com resultados de consultas de forma segura e eficiente \n
1. Trabalhando com PostgreSQL através da biblioteca Diesel
\n\nDiesel é um ORM e query builder para Rust que garante segurança de tipos em tempo de compilação. Para começar, adicione as dependências no Cargo.toml:
[dependencies]\ndiesel = { version = "2.1", features = ["postgres"] }\ndotenvy = "0.15"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\ntokio = { version = "1.0", features = ["full"] }\n\nConfiguração da conexão
\n\nCrie um arquivo .env com a URL do seu banco de dados:
DATABASE_URL=postgres://user:password@localhost/mydb\n\nAgora vamos escrever o código para conectar e criar uma tabela:
\n\nuse diesel::prelude::*;\nuse diesel::pg::PgConnection;\nuse dotenvy::dotenv;\nuse std::env;\n\npub fn establish_connection() -> PgConnection {\n dotenv().ok();\n let database_url = env::var("DATABASE_URL")\n .expect("DATABASE_URL must be set");\n PgConnection::establish(&database_url)\n .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))\n}\n\nDefinição do esquema e modelo
\n\nVamos criar a tabela users e o modelo Rust correspondente:
// schema.rs\ntable! {\n users (id) {\n id -> Int4,\n name -> Varchar,\n email -> Varchar,\n created_at -> Timestamp,\n }\n}\n\n// models.rs\n#[derive(Queryable, Selectable)]\n#[diesel(table_name = crate::schema::users)]\n#[diesel(check_for_backend(diesel::pg::Pg))]\npub struct User {\n pub id: i32,\n pub name: String,\n pub email: String,\n pub created_at: chrono::NaiveDateTime,\n}\n\n#[derive(Insertable)]\n#[diesel(table_name = crate::schema::users)]\npub struct NewUser {\n pub name: String,\n pub email: String,\n}\n\nOperações CRUD
\n\nExemplo de criação e leitura de usuários:
\n\nuse crate::models::{User, NewUser};\nuse crate::schema::users;\n\npub fn create_user(conn: &mut PgConnection, name: &str, email: &str) -> User {\n let new_user = NewUser {\n name: name.to_string(),\n email: email.to_string(),\n };\n\n diesel::insert_into(users::table)\n .values(&new_user)\n .returning(User::as_returning())\n .get_result(conn)\n .expect("Error saving new user")\n}\n\npub fn get_all_users(conn: &mut PgConnection) -> Vec {\n users::table\n .load::(conn)\n .expect("Error loading users")\n} \n\nComo você pode ver, o Diesel verifica tipos e nomes de colunas em tempo de compilação. Um erro no nome do campo resultará em um erro de compilação, não em uma falha em tempo de execução.
\n\n2. Trabalhando com MongoDB através do driver oficial
\n\nMongoDB é um banco de dados NoSQL que armazena dados em formato semelhante a JSON.