How to delete a record by ID in Flask-SQLAlchemy
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Deleting a row by primary key is a standard Flask-SQLAlchemy task, but it is worth doing in a way that is explicit about missing records and transaction boundaries. The basic pattern is to load the model instance, delete it from the session, and commit the transaction. From there, the details depend on whether you want a plain function, an API route, or bulk behavior.
The Normal Deletion Pattern
With modern Flask-SQLAlchemy built on SQLAlchemy 2 style sessions, the clearest approach is db.session.get followed by db.session.delete.
This approach is easy to read and gives you a chance to return a 404 when the ID does not exist.
Why Load the Record First?
Some developers look for a one-line delete by ID, but loading the object first has a few advantages:
- you can handle the missing-record case cleanly
- SQLAlchemy can run mapper events and cascades as expected
- the code is easy to extend with authorization or logging checks
If your application needs to verify ownership before deletion, this pattern gives you a clear place to do that.
For example:
Handling Errors Safely
A delete should be part of a transaction. If something fails during commit, roll the session back.
This becomes more important when foreign keys, cascades, or database constraints are involved.
Bulk Deletes Are Different
If you need to delete many rows by a filter, SQLAlchemy also supports delete statements. That is a different use case from deleting one record by ID.
This can be efficient, but it bypasses some instance-level ORM behavior. For a single record deletion where you care about application logic, loading the instance is usually the safer choice.
Older Examples You May Still See
Older Flask-SQLAlchemy examples often use User.query.get(user_id). That pattern exists in many codebases, but newer SQLAlchemy guidance favors session-based APIs such as db.session.get(User, user_id).
If you are maintaining legacy code, both styles may appear. For new code, prefer the session-based form because it matches current SQLAlchemy direction more closely.
Common Pitfalls
A common mistake is calling db.session.delete and forgetting db.session.commit. Without the commit, the row is marked for deletion in the session but not actually removed from the database.
Another mistake is assuming the ID exists. Trying to delete None will fail, so always check the lookup result first.
Developers also sometimes use bulk delete operations when they really need model-level behavior, cascades, or validation. Those cases are better served by loading the instance first.
Finally, if a commit fails, remember to call db.session.rollback(). A broken session should not be reused without cleanup.
Summary
- The standard pattern is
db.session.get, thendb.session.delete, thendb.session.commit. - Check for
Noneso missing IDs return a proper404. - Wrap commits in error handling when database constraints might fail.
- Use bulk delete statements only when you intentionally want statement-style behavior.
- Prefer session-based APIs in modern Flask-SQLAlchemy code.
Related reading
- How to delete all records from table in sqlite with Android?
- How to delete all the Existing tables in DynamoDb?
- How to delete duplicates on a MySQL table?
- How to delete from multiple tables in MySQL?
- How to delete a record in Django models?
- How to delete a specific line in a text file using Python?
- How to delete multiple rows in DynamoDB?
- How to delete N numbers of documents in mongodb

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.