Veritabanı Tümleştirmesi
Verileri kalıcı hâle getirin
Veritabanı Tümleştirmesi, CoddyKit'te ücretsiz bir Learn Rust Coding dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Learn Rust Coding öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Learn Rust Coding kursu toplamda 4 dersten oluşur.
Verileri Kalıcı Hâle Getirme
Şimdiye kadar API'miz verileri bellekte saklıyordu; bu veriler yeniden başlatma sırasında kaybolur. Gerçek hizmetlerin bir veritabanına ihtiyacı vardır. Bu derste bir Axum API'sini, Rust için eşzamansız ve derleme zamanında denetlenen bir SQL araç seti olan sqlx kullanarak PostgreSQL'e bağlayacağız.
Bağlantı havuzlarını, sorguları, satırları yapılara eşlemeyi ve havuzu paylaşılan durum olarak kullanmayı öğreneceksiniz.
sqlx Ekleme
İhtiyacınız olan özelliklerle sqlx'i ekleyin: bir çalışma zamanı, TLS ve bir veritabanı sürücüsü. Aşağıda Tokio kullanan bir Postgres kurulumu gösterilmektedir.
// Cargo.toml
// [dependencies]
// sqlx = { version = "0.7", features = [
// "runtime-tokio", "tls-rustls", "postgres", "macros"
// ] }Bağlantı Havuzu
Her istek için yeni bir bağlantı açmak yavaştır. Bir bağlantı havuzu, yeniden kullanılabilir bağlantılardan oluşan bir küme tutar. PgPoolOptions, veritabanı URL'sinden bir havuz oluşturur. Havuzu kopyalamak ucuzdur (dahili olarak referans sayımı kullanır); bu da onu paylaşılan durum için ideal hâle getirir.
use sqlx::postgres::PgPoolOptions;
async fn make_pool(url: &str) -> sqlx::PgPool {
PgPoolOptions::new()
.max_connections(5)
.connect(url)
.await
.expect("failed to connect")
}Havuzu Uygulama Durumu Olarak Kullanma
Havuzu .with_state(pool) ile Axum'a aktarın. Ardından işleyiciler State(pool): State<PgPool> alır. Havuz ucuza kopyalanabildiği için her istek aynı temel bağlantıları paylaşır.
use axum::{routing::get, Router};
use sqlx::PgPool;
fn build(pool: PgPool) -> Router {
Router::new()
.route("/todos", get(list_todos))
.with_state(pool)
}Sorgu Çalıştırma
sqlx::query işlevi ham SQL çalıştırır. SQL eklemelerini önlemek için parametreleri .bind(value) ile bağlayın; Postgres, $1 ve $2 yer tutucularını kullanır. Satır döndürmeyen yazma işlemleri için .execute(&pool) kullanın.
use sqlx::PgPool;
async fn insert_todo(pool: &PgPool, title: &str) -> Result<(), sqlx::Error> {
sqlx::query("INSERT INTO todos (title, done) VALUES ($1, $2)")
.bind(title)
.bind(false)
.execute(pool)
.await?;
Ok(())
}Satırları Yapılara Eşleme
Sorgu sonuçlarının doğrudan modele eşlenmesi için modeliniz üzerinde sqlx::FromRow türetin. Bir Vec<Todo> elde etmek için fetch_all ile query_as::<_, Todo> kullanın; tek bir satır içinse fetch_one kullanın.
use sqlx::{PgPool, FromRow};
#[derive(FromRow, serde::Serialize)]
struct Todo { id: i32, title: String, done: bool }
async fn all_todos(pool: &PgPool) -> Result<Vec<Todo>, sqlx::Error> {
let rows = sqlx::query_as::<_, Todo>("SELECT id, title, done FROM todos")
.fetch_all(pool)
.await?;
Ok(rows)
}Veritabanını Okuyan Bir İşleyici
Parçaları birleştirin: bir işleyici havuzu durumdan alır, bir sorgu çalıştırır ve JSON döndürür. İstemcinin panik yerine düzgün bir yanıt alması için veritabanı hatalarını 500 durumuna eşleyin.
use axum::{extract::State, Json, http::StatusCode};
use sqlx::PgPool;
async fn list_todos(
State(pool): State<PgPool>,
) -> Result<Json<Vec<Todo>>, StatusCode> {
match all_todos(&pool).await {
Ok(todos) => Ok(Json(todos)),
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
}
}Eklenen Satırları Döndürme
Postgres, RETURNING ile az önce eklediği satırı döndürebilir. Yeni kaydı, oluşturulan kimliği de içerecek şekilde tek bir gidiş-dönüşte almak için bunu query_as ve fetch_one ile birleştirin.
use sqlx::PgPool;
async fn create(pool: &PgPool, title: &str) -> Result<Todo, sqlx::Error> {
let todo = sqlx::query_as::<_, Todo>(
"INSERT INTO todos (title, done) VALUES ($1, false) \
RETURNING id, title, done")
.bind(title)
.fetch_one(pool)
.await?;
Ok(todo)
}Geçişler
Sorgular çalıştırılmadan önce şemanızın mevcut olması gerekir. sqlx, sırayla uygulanan migrations/ klasöründeki SQL dosyaları olan geçişleri destekler. Yeni bir veritabanının otomatik olarak hazırlanması için başlangıçta sqlx::migrate!() ile çalıştırın.
use sqlx::PgPool;
async fn run_migrations(pool: &PgPool) {
sqlx::migrate!("./migrations")
.run(pool)
.await
.expect("migrations failed");
}
// migrations/0001_init.sql contains the CREATE TABLE statements.İşlemler
Birden fazla yazma işleminin birlikte başarılı olması gerektiğinde bunları bir işlem içine alın. pool.begin() ile başlayın, sorguları işlem tutacağı üzerinde çalıştırın ve ardından commit çağırın. İşlemi tamamlamadan bırakırsanız sqlx otomatik olarak geri alır ve verilerin tutarlı kalmasını sağlar.
use sqlx::PgPool;
async fn transfer(pool: &PgPool) -> Result<(), sqlx::Error> {
let mut tx = pool.begin().await?;
sqlx::query("UPDATE accounts SET balance = balance - 10 WHERE id = 1")
.execute(&mut *tx).await?;
sqlx::query("UPDATE accounts SET balance = balance + 10 WHERE id = 2")
.execute(&mut *tx).await?;
tx.commit().await?;
Ok(())
}Yapılandırma ve Gizli Bilgiler
Veritabanı kimlik bilgilerini hiçbir zaman doğrudan koda yazmayın. DATABASE_URL değerini ortamdan okuyun; geliştirme sırasında bu değer genellikle dotenvy kasasıyla bir .env dosyasından yüklenir. Üretimde platform, bu değeri bir ortam değişkeni olarak sağlar.
use std::env;
async fn connect_from_env() -> sqlx::PgPool {
let url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
make_pool(&url).await
}Kısa Kontrol
Veritabanı tümleştirmesi hakkındaki anlayışınızı test edin.
Özet
Bir veritabanını tümleştirdiniz:
PgPoolbağlantı havuzu kullanın ve bunu.with_statearacılığıyla paylaşın.- Yazma işlemleri için
query/execute; türü belirli okumalar içinFromRowilequery_askullanın. - SQL eklemelerini önlemek için parametreleri her zaman bağlayın.
RETURNINGeklenen satırları getirir; işlemler yazma işlemlerini atomik olarak gruplandırır.- Geçişleri başlangıçta çalıştırın ve
DATABASE_URLdeğerini ortamdan okuyun.
Sıkça Sorulan Sorular
“Veritabanı Tümleştirmesi” dersi ücretsiz mi?
Evet — “Veritabanı Tümleştirmesi” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Learn Rust Coding kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Learn Rust Coding kursu toplamda 4 dersten oluşur.
“Veritabanı Tümleştirmesi” dersinde ne öğreneceğim?
Verileri kalıcı hâle getirin Learn Rust Coding ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Learn Rust Coding öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Learn Rust Coding, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Veritabanı Tümleştirmesi” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Learn Rust Coding dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Learn Rust Coding dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Proje Kurulumu
- Uç Noktalar ve Modeller
- Veritabanı Tümleştirmesi
- API'yi Test Etme