diff --git a/app/database.py b/app/database.py index 827e974..93a25b5 100644 --- a/app/database.py +++ b/app/database.py @@ -2,15 +2,17 @@ from sqlmodel import create_engine, SQLModel, Session from dotenv import load_dotenv import os +# Get database configuration load_dotenv() - DATABASE_URL = os.getenv("DATABASE_URL") if not DATABASE_URL: raise ValueError("DATABASE_URL environment variable is not set") +# Create database engine engine = create_engine(DATABASE_URL, echo=True) SQLModel.metadata.create_all(engine) +# Get database session def get_session(): with Session(engine) as session: yield session diff --git a/app/main.py b/app/main.py index 402b1e0..f45fe76 100644 --- a/app/main.py +++ b/app/main.py @@ -1,19 +1,23 @@ -from fastapi import FastAPI +from fastapi import FastAPI, HTTPException from sqlmodel import SQLModel, Session, select +from typing import List from .database import engine from .models import Author, Book app = FastAPI() +# Initialize the database @app.on_event("startup") def on_startup(): SQLModel.metadata.create_all(engine) +# Root endpoint @app.get("/") -async def read_root(): - return {"message": "Hello, FastAPI with SQLModel and PostgreSQL!"} +async def hello_world(): + return {"message": "Hello world!"} -@app.post("/authors/") +# Create an author +@app.post("/authors/", response_model=Author) def create_author(author: Author): with Session(engine) as session: session.add(author) @@ -21,13 +25,39 @@ def create_author(author: Author): session.refresh(author) return author -@app.get("/authors/") +# Read authors +@app.get("/authors/", response_model=List[Author]) def read_authors(): with Session(engine) as session: authors = session.exec(select(Author)).all() return authors -@app.post("/books/") +# Update an author +@app.put("/authors/{author_id}", response_model=Author) +def update_author(author_id: int, author: Author): + with Session(engine) as session: + db_author = session.get(Author, author_id) + if not db_author: + raise HTTPException(status_code=404, detail="Author not found") + db_author.name = author.name + session.add(db_author) + session.commit() + session.refresh(db_author) + return db_author + +# Delete an author +@app.delete("/authors/{author_id}") +def delete_author(author_id: int): + with Session(engine) as session: + db_author = session.get(Author, author_id) + if not db_author: + raise HTTPException(status_code=404, detail="Author not found") + session.delete(db_author) + session.commit() + return {"message": "Author deleted"} + +# Create a book +@app.post("/books/", response_model=Book) def create_book(book: Book): with Session(engine) as session: session.add(book) @@ -35,8 +65,34 @@ def create_book(book: Book): session.refresh(book) return book -@app.get("/books/") +# Read books +@app.get("/books/", response_model=List[Book]) def read_books(): with Session(engine) as session: books = session.exec(select(Book)).all() return books + +# Update a book +@app.put("/books/{book_id}", response_model=Book) +def update_book(book_id: int, book: Book): + with Session(engine) as session: + db_book = session.get(Book, book_id) + if not db_book: + raise HTTPException(status_code=404, detail="Book not found") + db_book.title = book.title + db_book.authors = book.authors + session.add(db_book) + session.commit() + session.refresh(db_book) + return db_book + +# Delete a book +@app.delete("/books/{book_id}") +def delete_book(book_id: int): + with Session(engine) as session: + db_book = session.get(Book, book_id) + if not db_book: + raise HTTPException(status_code=404, detail="Book not found") + session.delete(db_book) + session.commit() + return {"message": "Book deleted"} diff --git a/app/models.py b/app/models.py index 2257560..7405afe 100644 --- a/app/models.py +++ b/app/models.py @@ -1,16 +1,19 @@ from typing import Optional, List from sqlmodel import SQLModel, Field, Relationship +# Relationship model class AuthorBookLink(SQLModel, table=True): author_id: int | None = Field(default=None, foreign_key="author.id", primary_key=True) book_id: int | None = Field(default=None, foreign_key="book.id", primary_key=True) +# Author model class Author(SQLModel, table=True): id: Optional[int] = Field(primary_key=True, index=True) name: str books: List["Book"] = Relationship(back_populates="authors", link_model=AuthorBookLink) +# Book model class Book(SQLModel, table=True): id: Optional[int] = Field(primary_key=True, index=True) title: str