CRUD-operationer med SQLAlchemy
Implementér Create-, Read-, Update- og Delete-operationer til Deres API-endpoints ved hjælp af SQLAlchemy ORM.
CRUD-operationer med SQLAlchemy er en gratis Bootcamp i FastAPI-backendudvikling-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Bootcamp i FastAPI-backendudvikling, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Bootcamp i FastAPI-backendudvikling-kurset indeholder 4 lektioner i alt.
CRUD-handlinger: Kernen
Velkommen til lektion 3! I dag lærer du at mestre CRUD-handlinger ved hjælp af FastAPI og SQLAlchemy. CRUD står for:
- Create: Tilføjelse af nye data.
- Read: Hentning af eksisterende data.
- Update: Ændring af eksisterende data.
- Delete: Fjernelse af data.
Disse fire handlinger er grundlaget for næsten alle applikationer, der interagerer med en database.
Opsætning: Modeller og session
Før du går i gang med CRUD, skal du konfigurere din SQLAlchemy-model og dine Pydantic-skemaer. Du bruger en SQLite-database i hukommelsen i de kørbare eksempler.
Først din SQLAlchemy-Todo-model, der repræsenterer en opgave:
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)Og Pydantic-skemaer til forespørgsel/svar:
from pydantic import BaseModel
class TodoCreate(BaseModel):
title: str
description: str = ""
completed: bool = False
class TodoResponse(TodoCreate):
id: int
class Config:
orm_mode = TrueDatabasesession i FastAPI
I FastAPI håndterer du databasesessioner ved hjælp af afhængigheder. Det sikrer, at hver forespørgsel får en ny session, og at den lukkes korrekt.
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()Denne get_db-funktion injiceres i vores FastAPI-slutpunkter.
Opret: FastAPI-slutpunkt
Hvis du vil oprette et nyt element, bruger du en POST-forespørgsel. Slutpunktet modtager data via en Pydantic-model og bruger SQLAlchemy til at føje dem til databasen.
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
# ... (imports for Base, Todo, TodoCreate, TodoResponse, get_db, engine)
app = FastAPI()
Base.metadata.create_all(bind=engine) # Create tables
@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) # Refresh to get ID and updated fields
return db_todoKaldet db.refresh() opdaterer vores db_todo-objekt med værdier, der er genereret af databasen, for eksempel id.
Opret: SQLAlchemy-demo
Lad os se SQLAlchemys trin til at oprette data i praksis. Dette kørbare script føjer en ny todo til vores database i hukommelsen.
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()Læs: FastAPI-slutpunkter
Hvis du vil læse data, bruger du GET-forespørgsler. Du har to slutpunkter: ét til at hente alle todo-elementer og ét til at hente et enkelt todo-element ud fra dets ID.
# ... (FastAPI app, imports, get_db, models)
@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 not found")
return todoDu bruger .all() til at hente en liste og .first() til at hente et enkelt element. Husk at håndtere tilfælde, hvor et element ikke findes!
Læs: SQLAlchemy-demo
Lad os køre en demonstration af handlingen Læs. Først opretter du nogle todo-elementer, derefter henter du dem alle og til sidst et bestemt element ud fra dets ID.
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()Opdater: FastAPI-slutpunkt
Handlingen Opdater (PUT eller PATCH) giver dig mulighed for at ændre et eksisterende element. Typisk finder du elementet ud fra dets ID, opdaterer dets attributter og gennemfører ændringerne.
# ... (FastAPI app, imports, get_db, models)
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 not found")
# Update fields only if provided
for key, value in todo_update.dict(exclude_unset=True).items():
setattr(db_todo, key, value)
db.add(db_todo) # Re-add to session for update tracking
db.commit()
db.refresh(db_todo)
return db_todoBrug af exclude_unset=True i Pydantic sikrer, at kun de angivne felter bliver opdateret.
Opdater: SQLAlchemy-demo
Her er et kørbart eksempel, der viser, hvordan du opdaterer titlen og færdiggørelsesstatussen for et todo-element ved hjælp af SQLAlchemy.
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()Slet: FastAPI-slutpunkt
Handlingen Slet fjerner et element fra databasen. Det gøres normalt med en DELETE-forespørgsel, der målrettes et element ud fra dets ID.
# ... (FastAPI app, imports, get_db, models)
@app.delete("/todos/{todo_id}", status_code=204) # 204 No Content for successful deletion
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 not found")
db.delete(db_todo)
db.commit()
return {"message": "Todo deleted successfully"} # FastAPI automatically handles 204En vellykket sletning returnerer ofte statuskoden 204 No Content, hvilket betyder, at forespørgslen blev gennemført, men at der ikke er noget indhold at sende tilbage.
Slet: SQLAlchemy-demo
Lad os køre et script, der demonstrerer, hvordan du sletter et todo-element. Først opretter du et, derefter sletter du det og forsøger at læse det igen for at bekræfte, at det er fjernet.
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-udfordring
Du har lært de grundlæggende CRUD-handlinger! Nu kan du teste din forståelse af, hvordan SQLAlchemys metoder svarer til disse handlinger.
Opsummering og næste trin
Godt klaret! I denne lektion har du lært at implementere de grundlæggende CRUD-handlinger i FastAPI ved hjælp af SQLAlchemy:
- Opret (POST): Brug af
db.add(),db.commit()ogdb.refresh(). - Læs (GET): Brug af
db.query().all()til lister ogdb.query().filter().first()til enkelte elementer. - Opdatér (PUT): Hentning af et element, ændring af dets attributter og derefter
db.commit()ogdb.refresh(). - Slet (DELETE): Hentning af et element og derefter
db.delete()ogdb.commit().
Disse færdigheder er afgørende for at bygge enhver datadrevet API. På det næste kursus går vi i dybden med avancerede emner som brugerautentificering og -autorisation for at sikre dine API-slutpunkter!
Lær Bootcamp i FastAPI-backendudvikling med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 21
- Lektioner
- 84
Ofte stillede spørgsmål
Er lektionen “CRUD-operationer med SQLAlchemy” gratis?
Ja — alle 3 lektioner i læringssporet Bootcamp i FastAPI-backendudvikling, inklusive “CRUD-operationer med SQLAlchemy”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Bootcamp i FastAPI-backendudvikling-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “CRUD-operationer med SQLAlchemy”?
Implementér Create-, Read-, Update- og Delete-operationer til Deres API-endpoints ved hjælp af SQLAlchemy ORM. Du øver dig i Bootcamp i FastAPI-backendudvikling med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Bootcamp i FastAPI-backendudvikling?
Der kræves ingen tidligere erfaring. Bootcamp i FastAPI-backendudvikling på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “CRUD-operationer med SQLAlchemy”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Bootcamp i FastAPI-backendudvikling-lektion?
Ja. Alle Bootcamp i FastAPI-backendudvikling-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Grundlæggende SQLAlchemy ORM
- Forbind FastAPI til PostgreSQL
- CRUD-operationer med SQLAlchemy
- Databasemigrationer med Alembic