To read one product, a client puts its id in the path: /products/3. A route written as /products/<int:product_id> catches that piece of the path, turns it into a whole number and passes it to your function.
This time the database does the searching, with a WHERE condition. You never paste the value into the SQL text: you write a placeholder, ?, and pass the value separately, in a tuple. An id matches at most one row, so .fetchone() gives that row, or None when the query found nothing. For example, with a table books:
row = db.execute("SELECT * FROM books WHERE year = ?", (1965,)).fetchone()
if row is None:
print("No book from 1965")
A tuple with one item needs a comma: (1965,). When no row matches, the client asked for something that doesn't exist, so the answer is 404 with an error message.
GET /products/3 → 200 {"id": 3, "name": "Lamp", "price": 29, "category": "home", "stock": 1}
GET /products/8 → 200 {"id": 8, "name": "Gift card", "price": 50, "category": null, "stock": 999}
GET /products/99 → 404 {"error": "Product not found"}
GET /products/0 → 404 {"error": "Product not found"}
Your task: add GET /products/<int:product_id>, which asks the database for that product with a placeholder and answers it as JSON, or {"error": "Product not found"} with the status 404.
Assignment
Follow the Coding Tutorial to add the route and its function get_product.
Hintfetchone() gives None when the query finds nothing. Check for it before you turn the row into a dictionary with dict(row).
Free plan: 30 tutor messages. PRO is unlimited.
