I'm building a rest API using Flask and SQLAlchemy.
I've encountered one problem: if I delete a resource using a HTTP DELETE that internally calls a SQLAlchemy delete, if I recreate that one element from the database and I try to access the resource using GET I will receive 404 Not Found.
The log indicates:
2021-10-24 11:37:21,736 INFO sqlalchemy.engine.Engine [cached since [..]s ago] {'isbn_1': '12312', 'param_1': 1}
.
It looks that the method that does the fetch from the database is for some reason stuck on the state in which the resource does not exist, even if I recreated it with the same details after the HTTP Delete.
This is surely related to the cache, and I'm not sure how to handle this situation.
Model - sqlalchemy
from books import Book
from db import Session, engine
local_session = Session(bind=engine)
def get_book_by_isbn(isbn):
"""
Wrapper for an ORM call that is retrieving a book by its ISBN.
:param isbn: isbn code of the book that is to be retrieved
"""
response = OperationResponseWrapper()
try:
response.payload = local_session.query(Book).filter(Book.isbn == isbn).first()
if not response.payload:
response.completed_operation = False
else:
response.completed_operation = True
except Exception as e:
response.erorr = e
response.completed_operation = False
return response
def delete_book_by_isbn(isbn):
"""
Wrapper for an ORM call that is deleting a book by its ISBN.
:param isbn: isbn code of the book that is to be deleted
"""
response = OperationResponseWrapper()
try:
book_to_delete = local_session.query(Book).filter(Book.isbn == isbn).first()
if book_to_delete:
local_session.delete(book_to_delete)
local_session.commit()
else:
response.completed_operation = False
except Exception as e:
response.completed_operation = False
response.erorr = e
return response
Controller - Flask
from model import get_book_by_isbn, delete_book_by_isbn
[..]
@app.route('/api/bookcollection/books/<isbn>', methods=['GET'])
def get_book(isbn):
"""
Method that handles a GET request for a book by the ISBN code.
:param isbn: isbn code of the book that is to be retrieved
"""
db_response = get_book_by_isbn(str(isbn))
body = ''
status = 200
if db_response.erorr:
status = 404
body = ErrorDto(404, str(db_response.erorr), 'EXCEPTION')
elif not db_response.completed_operation:
status = 404
body = ErrorDto(404, 'Requested book does not exist.', 'INVALID_OPERATION')
else:
status = 200
links = LinkDto(request.path, 'books', request.method)
body = BookDto(db_response.payload, links)
return jsonify(body.__dict__), status
@app.route('/api/bookcollection/books/<isbn>', methods=['DELETE'])
def delete_book(isbn):
"""
Method that handles a DELETE request for a book by the ISBN code.
:param isbn: isbn code of the book that is to be deleted
"""
db_response = delete_book_by_isbn(isbn)
body = ''
status = 200
if db_response.erorr:
status = 404
body = ErrorDto(404, str(db_response.erorr), 'EXCEPTION')
elif not db_response.completed_operation:
status = 404
body = ErrorDto(404, 'Requested book does not exist.', 'INVALID_OPERATION')
else:
status = 200
links = LinkDto(request.path, 'books', request.method)
body = StatusDto(200, 'Operation was completed successfully.', links)
return jsonify(body.__dict__), status