Initial Commit

This commit is contained in:
2026-02-23 16:42:35 +01:00
commit a5c93d1f8a
12 changed files with 458 additions and 0 deletions

99
app/routers/books.py Normal file
View File

@ -0,0 +1,99 @@
from datetime import date
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import text
from app.database import get_db
router = APIRouter(prefix="/books", tags=["Books"])
@router.get("/")
async def get_all_books(db: AsyncSession = Depends(get_db)):
result = await db.execute(text("""
SELECT b.id, b.title, b.genre, b.published, a.name AS author
FROM books b
JOIN authors a ON a.id = b.author_id
ORDER BY b.title
"""))
return result.mappings().all()
@router.get("/{book_id}")
async def get_book(book_id: int, db: AsyncSession = Depends(get_db)):
result = await db.execute(
text("""
SELECT b.*, a.name AS author_name
FROM books b
JOIN authors a ON a.id = b.author_id
WHERE b.id = :id
"""),
{"id": book_id}
)
book = result.mappings().one_or_none()
if not book:
raise HTTPException(status_code=404, detail="Book not found")
return book
@router.post("/", status_code=201)
async def create_book(
title: str, author_id: int, genre: str = None,
published: date = None, description: str = None,
db: AsyncSession = Depends(get_db)
):
# Check author exists
result = await db.execute(
text("SELECT id FROM authors WHERE id = :id"), {"id": author_id}
)
if not result.one_or_none():
raise HTTPException(status_code=404, detail="Author not found")
await db.execute(
text("""
INSERT INTO books (title, author_id, genre, published, description)
VALUES (:title, :author_id, :genre, :published, :description)
"""),
{"title": title, "author_id": author_id, "genre": genre,
"published": published, "description": description}
)
await db.commit()
return {"message": f"Book '{title}' created"}
@router.put("/{book_id}")
async def update_book(
book_id: int, title: str = None, genre: str = None,
description: str = None, db: AsyncSession = Depends(get_db)
):
result = await db.execute(
text("SELECT id FROM books WHERE id = :id"), {"id": book_id}
)
if not result.one_or_none():
raise HTTPException(status_code=404, detail="Book not found")
await db.execute(
text("""
UPDATE books
SET title = COALESCE(:title, title),
genre = COALESCE(:genre, genre),
description = COALESCE(:description, description)
WHERE id = :id
"""),
{"id": book_id, "title": title, "genre": genre, "description": description}
)
await db.commit()
return {"message": "Book updated"}
@router.delete("/{book_id}", status_code=204)
async def delete_book(book_id: int, db: AsyncSession = Depends(get_db)):
result = await db.execute(
text("SELECT id FROM books WHERE id = :id"), {"id": book_id}
)
if not result.one_or_none():
raise HTTPException(status_code=404, detail="Book not found")
await db.execute(
text("DELETE FROM books WHERE id = :id"), {"id": book_id}
)
await db.commit()