Arbeiten mit Datenbanken in Rust: PostgreSQL und MongoDB für Anfänger
\n\nRust ist eine moderne systemnahe Programmiersprache, die aufgrund ihrer Leistung und Sicherheit an Popularität gewinnt. Aber wie arbeitet man mit Datenbanken in Rust? In diesem Artikel behandeln wir die Verbindung und die Durchführung grundlegender Operationen mit zwei beliebten DBMS: dem relationalen PostgreSQL und der dokumentenorientierten MongoDB. Das Material richtet sich an Anfänger, die mit den Grundlagen von Rust vertraut sind.
\n\nWarum sind Rust und Datenbanken eine gute Kombination?
\n\nRust bietet ein strenges Typsystem und Speichersicherheitsgarantien, was besonders bei der Arbeit mit Daten wertvoll ist. Speicherzugriffsfehler, die für C/C++ typisch sind, werden bereits zur Kompilierzeit ausgeschlossen. Darüber hinaus umfasst das Rust-Ökosystem ausgereifte Bibliotheken für die Interaktion mit Datenbanken: diesel für PostgreSQL und den offiziellen Treiber für MongoDB.
In diesem Artikel lernen wir:
\n- \n
- Verbindung zu PostgreSQL und MongoDB von Rust aus herstellen \n
- CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Löschen) durchführen \n
- Sicher und effizient mit Abfrageergebnissen arbeiten \n
1. Arbeiten mit PostgreSQL über die Bibliothek Diesel
\n\nDiesel ist ein ORM und Query Builder für Rust, der Typsicherheit auf Kompilierungsebene gewährleistet. Fügen Sie zunächst die Abhängigkeiten zu Ihrer Cargo.toml hinzu:
[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\nVerbindung einrichten
\n\nErstellen Sie eine .env-Datei mit der URL Ihrer Datenbank:
DATABASE_URL=postgres://user:password@localhost/mydb\n\nJetzt schreiben wir den Code für die Verbindung und das Erstellen einer Tabelle:
\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\nSchema und Modell definieren
\n\nErstellen wir eine Tabelle users und das entsprechende Rust-Modell:
// 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\nCRUD-Operationen
\n\nBeispiel für das Erstellen und Lesen von Benutzern:
\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\nWie Sie sehen, überprüft Diesel Typen und Spaltennamen zur Kompilierzeit. Ein Fehler im Feldnamen führt zu einem Kompilierungsfehler und nicht zu einem Laufzeitfehler.
\n\n2. Arbeiten mit MongoDB über den offiziellen Treiber
\n\nMongoDB ist eine NoSQL-Datenbank, die Daten im Format JSON-ähnlicher