0Pricing
FastAPI Backend Development Bootcamp · Ders

SQLAlchemy ile CRUD İşlemleri

SQLAlchemy ORM kullanarak API uç noktalarınız için oluşturma, okuma, güncelleme ve silme işlemlerini uygulayın.

SQLAlchemy ile CRUD İşlemleri, CoddyKit'te ücretsiz bir FastAPI Backend Development Bootcamp 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, FastAPI Backend Development Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. FastAPI Backend Development Bootcamp kursu toplamda 4 dersten oluşur.

CRUD Operations: The Core

3. Derse hoş geldiniz! Bugün, FastAPI ve SQLAlchemy kullanarak CRUD işlemlerinde ustalaşacağız. CRUD şunları ifade eder:

  • Create (Oluşturma): Yeni veri ekleme.
  • Read (Okuma): Mevcut verileri alma.
  • Update (Güncelleme): Mevcut verileri değiştirme.
  • Delete (Silme): Verileri kaldırma.

Bu dört işlem, veritabanı ile etkileşime giren hemen hemen her uygulamanın temelini oluşturur.

Setup: Models & Session

CRUD işlemlerine dalmadan önce, SQLAlchemy modelimizi ve Pydantic şemalarımızı hazırlayalım. Çalıştırılabilir örneklerimiz için bellek içi (in-memory) bir SQLite veritabanı kullanacağız.

İlk olarak, bir görevi temsil etmesi için SQLAlchemy Todo modelimiz:

from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Todo(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    description = Column(String, default="")
    completed = Column(Boolean, default=False)

Ve istek/yanıt işlemleri için Pydantic şemalarımız:

from pydantic import BaseModel

class TodoCreate(BaseModel):
    title: str
    description: str = ""
    completed: bool = False

class TodoResponse(TodoCreate):
    id: int

    class Config:
        orm_mode = True

Database Session in FastAPI

FastAPI'de veritabanı oturumlarını bağımlılıklar (dependencies) kullanarak yönetiriz. Bu, her isteğin yeni bir oturum almasını ve bu oturumun düzgün bir şekilde kapatılmasını sağlar.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

Bu get_db fonksiyonu, FastAPI uç noktalarımıza (endpoints) enjekte edilecektir.

Create: FastAPI Endpoint

Yeni bir öğe oluşturmak için bir POST isteği kullanacağız. Uç nokta, verileri bir Pydantic modeli aracılığıyla alacak ve bunu veritabanına eklemek için SQLAlchemy kullanacaktır.

from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

# ... (Base, Todo, TodoCreate, TodoResponse, get_db, engine için içe aktarmalar)

app = FastAPI()
Base.metadata.create_all(bind=engine) # Tabloları oluştur

@app.post("/todos/", response_model=TodoResponse)
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
    db_todo = Todo(title=todo.title, description=todo.description, completed=todo.completed)
    db.add(db_todo)
    db.commit()
    db.refresh(db_todo) # ID ve güncellenmiş alanları almak için yenile
    return db_todo

db.refresh() çağrısı, db_todo nesnemizi id gibi veritabanı tarafından oluşturulan değerlerle günceller.

Create: SQLAlchemy Demo

SQLAlchemy 'Create' adımlarını iş başında görelim. Bu çalıştırılabilir betik, bellek içi veritabanımıza yeni bir yapılacak iş ekleyecektir.

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 1. Setup Database and Model
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Todo(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    description = Column(String, default="")
    completed = Column(Boolean, default=False)

# 2. Create Tables
Base.metadata.create_all(bind=engine)

# 3. Create a Session
db = SessionLocal()

# 4. Create Operation (C)
print("--- Creating a new Todo ---")
new_todo = Todo(title="Learn FastAPI", description="Complete CoddyKit lesson", completed=False)
db.add(new_todo)
db.commit()
db.refresh(new_todo)
print(f"Created Todo: ID={new_todo.id}, Title='{new_todo.title}'")

# 5. Close Session
db.close()

Read: FastAPI Endpoints

Verileri okumak için GET isteklerini kullanırız. İki uç noktamız olacak: biri tüm yapılacaklar listesini (todos) almak için, diğeri ise ID'sine göre tek bir yapılacak öğeyi almak için.

# ... (FastAPI uygulaması, içe aktarmalar, get_db, modeller)

@app.get("/todos/", response_model=list[TodoResponse])
def read_todos(db: Session = Depends(get_db)):
    todos = db.query(Todo).all()
    return todos

@app.get("/todos/{todo_id}", response_model=TodoResponse)
def read_todo(todo_id: int, db: Session = Depends(get_db)):
    todo = db.query(Todo).filter(Todo.id == todo_id).first()
    if todo is None:
        raise HTTPException(status_code=404, detail="Todo bulunamadı")
    return todo

Bir liste almak için .all(), tek bir öğe almak için ise .first() kullanırız. Bir öğenin bulunamadığı durumları yönetmeyi unutmayın!

Read: SQLAlchemy Demo

'Oku' işlemi için bir demo çalıştıralım. Öncelikle birkaç yapılacak iş (todo) oluşturacağız, ardından hepsini getireceğiz ve son olarak ID'ye göre belirli bir tanesini getireceğiz.

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Setup Database and Model (same as before)
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Todo(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    description = Column(String, default="")
    completed = Column(Boolean, default=False)

Base.metadata.create_all(bind=engine)
db = SessionLocal()

# Create some initial Todos for reading
todo1 = Todo(title="Buy groceries")
todo2 = Todo(title="Walk the dog")
db.add_all([todo1, todo2])
db.commit()
db.refresh(todo1)
db.refresh(todo2)
print(f"Created Todos: {todo1.id}, {todo2.id}\n")

# Read Operation (R)
print("--- Reading all Todos ---")
all_todos = db.query(Todo).all()
for t in all_todos:
    print(f"ID={t.id}, Title='{t.title}'")

print("\n--- Reading a specific Todo (ID 1) ---")
specific_todo = db.query(Todo).filter(Todo.id == 1).first()
if specific_todo:
    print(f"Found Todo: ID={specific_todo.id}, Title='{specific_todo.title}'")
else:
    print("Todo with ID 1 not found.")

print("\n--- Reading a non-existent Todo (ID 99) ---")
non_existent_todo = db.query(Todo).filter(Todo.id == 99).first()
if non_existent_todo:
    print(f"Found Todo: ID={non_existent_todo.id}")
else:
    print("Todo with ID 99 not found.")

db.close()

Update: FastAPI Endpoint

Güncelleme (Update) işlemi (PUT veya PATCH), mevcut bir öğeyi değiştirmemize olanak tanır. Genellikle öğeyi ID ile bulur, niteliklerini günceller ve değişiklikleri kaydederiz.

# ... (FastAPI uygulaması, içe aktarmalar, get_db, modeller)

class TodoUpdate(BaseModel):
    title: str | None = None
    description: str | None = None
    completed: bool | None = None

@app.put("/todos/{todo_id}", response_model=TodoResponse)
def update_todo(todo_id: int, todo_update: TodoUpdate, db: Session = Depends(get_db)):
    db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
    if db_todo is None:
        raise HTTPException(status_code=404, detail="Todo bulunamadı")
    
    # Alanları yalnızca sağlandıklarında güncelle
    for key, value in todo_update.dict(exclude_unset=True).items():
        setattr(db_todo, key, value)
    
    db.add(db_todo) # Güncelleme takibi için oturuma tekrar ekle
    db.commit()
    db.refresh(db_todo)
    return db_todo

Pydantic içinde exclude_unset=True kullanmak, yalnızca sağlanan alanların güncellenmesini sağlar.

Update: SQLAlchemy Demo

İşte SQLAlchemy kullanarak bir yapılacaklar öğesinin başlığını ve tamamlanma durumunu nasıl güncelleyeceğinizi gösteren çalıştırılabilir bir örnek.

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Setup Database and Model
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Todo(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    description = Column(String, default="")
    completed = Column(Boolean, default=False)

Base.metadata.create_all(bind=engine)
db = SessionLocal()

# Create an initial Todo to update
initial_todo = Todo(title="Draft report", completed=False)
db.add(initial_todo)
db.commit()
db.refresh(initial_todo)
print(f"Created Todo: ID={initial_todo.id}, Title='{initial_todo.title}', Completed={initial_todo.completed}\n")

# Update Operation (U)
print(f"--- Updating Todo ID {initial_todo.id} ---")
todo_to_update = db.query(Todo).filter(Todo.id == initial_todo.id).first()

if todo_to_update:
    todo_to_update.title = "Finalize report"
    todo_to_update.completed = True
    db.commit()
    db.refresh(todo_to_update)
    print(f"Updated Todo: ID={todo_to_update.id}, Title='{todo_to_update.title}', Completed={todo_to_update.completed}")
else:
    print(f"Todo with ID {initial_todo.id} not found.")

db.close()

Delete: FastAPI Endpoint

Silme (Delete) işlemi, veritabanından bir öğeyi kaldırır. Bu işlem genellikle bir öğeyi kimliğine (ID) göre hedefleyen bir DELETE isteği ile yapılır.

# ... (FastAPI uygulaması, içe aktarmalar, get_db, modeller)

@app.delete("/todos/{todo_id}", status_code=204) # Başarılı silme işlemi için 204 No Content
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
    db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
    if db_todo is None:
        raise HTTPException(status_code=404, detail="Todo bulunamadı")
    
    db.delete(db_todo)
    db.commit()
    return {"message": "Todo başarıyla silindi"} # FastAPI otomatik olarak 204 durum kodunu yönetir

Başarılı bir silme işlemi genellikle 204 No Content durum kodunu döndürür; bu, isteğin yerine getirildiği ancak geri gönderilecek bir içerik olmadığı anlamına gelir.

Delete: SQLAlchemy Demo

Bir yapılacaklar öğesini silmeyi göstermek için bir betik çalıştıralım. Bir tane oluşturacağız, ardından sileceğiz ve kaldırıldığını doğrulamak için tekrar okumaya çalışacağız.

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Setup Database and Model
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Todo(Base):
    __tablename__ = "todos"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    description = Column(String, default="")
    completed = Column(Boolean, default=False)

Base.metadata.create_all(bind=engine)
db = SessionLocal()

# Create an initial Todo to delete
todo_to_delete = Todo(title="Clean garage")
db.add(todo_to_delete)
db.commit()
db.refresh(todo_to_delete)
print(f"Created Todo: ID={todo_to_delete.id}, Title='{todo_to_delete.title}'\n")

# Delete Operation (D)
print(f"--- Deleting Todo ID {todo_to_delete.id} ---")
db.delete(todo_to_delete)
db.commit()
print(f"Todo ID {todo_to_delete.id} deleted.\n")

# Verify deletion by trying to read it
print("--- Verifying deletion ---")
verify_deleted = db.query(Todo).filter(Todo.id == todo_to_delete.id).first()
if verify_deleted is None:
    print(f"Successfully verified: Todo ID {todo_to_delete.id} is no longer in the database.")
else:
    print(f"Error: Todo ID {todo_to_delete.id} still found.")

db.close()

CRUD Challenge

Temel CRUD işlemlerini öğrendiniz! Şimdi, SQLAlchemy metotlarının bu işlemlerle nasıl eşleştiğine dair anlayışınızı test edelim.

Recap & Next Steps

Harika iş çıkardın! Bu derste, SQLAlchemy kullanarak FastAPI'de temel CRUD işlemlerini uygulamayı öğrendin:

  • Create (POST): db.add(), db.commit() ve db.refresh() kullanarak.
  • Read (GET): Listeler için db.query().all() ve tekil öğeler için db.query().filter().first() kullanarak.
  • Update (PUT): Bir öğeyi getirip niteliklerini değiştirdikten sonra db.commit() ve db.refresh() kullanarak.
  • Delete (DELETE): Bir öğeyi getirip ardından db.delete() ve db.commit() kullanarak.

Bu beceriler, veri odaklı herhangi bir API oluşturmak için çok önemlidir. Bir sonraki kursta, API uç noktalarınızı güvenli hale getirmek için kullanıcı kimlik doğrulaması ve yetkilendirme gibi ileri düzey konulara dalacağız!

Sıkça Sorulan Sorular

“SQLAlchemy ile CRUD İşlemleri” dersi ücretsiz mi?

Evet — “SQLAlchemy ile CRUD İşlemleri” 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 FastAPI Backend Development Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. FastAPI Backend Development Bootcamp kursu toplamda 4 dersten oluşur.

“SQLAlchemy ile CRUD İşlemleri” dersinde ne öğreneceğim?

SQLAlchemy ORM kullanarak API uç noktalarınız için oluşturma, okuma, güncelleme ve silme işlemlerini uygulayın. FastAPI Backend Development Bootcamp 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.

FastAPI Backend Development Bootcamp öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te FastAPI Backend Development Bootcamp, 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.

“SQLAlchemy ile CRUD İşlemleri” 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 FastAPI Backend Development Bootcamp dersinde kod yazıp çalıştırabilir miyim?

Evet. Her FastAPI Backend Development Bootcamp 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

  1. SQLAlchemy ORM Temelleri
  2. FastAPI'yi PostgreSQL'e Bağlama
  3. SQLAlchemy ile CRUD İşlemleri
  4. Alembic ile Veritabanı Geçişleri
← FastAPI Backend Development Bootcamp Sayfasına Dön