What if you could change your database without rewriting your whole app?
Why Repository pattern for data access in Flask? - Purpose & Use Cases
Imagine building a Flask app where you write raw database queries everywhere in your code to get or save data.
Every time you want to change the database or fix a bug, you have to hunt down all those queries scattered around.
Writing database code everywhere makes your app messy and hard to fix.
If the database changes, you must update many places, risking mistakes and bugs.
This slows down development and makes your app fragile.
The Repository pattern creates a single place to handle all data access.
Your app talks to this repository instead of the database directly.
This keeps your code clean, easy to maintain, and ready for changes.
db.session.query(User).filter_by(id=1).first()
db.session.add(new_user)
db.session.commit()user_repo.get_user_by_id(1)
user_repo.add_user(new_user)
user_repo.commit()You can change how data is stored without touching the rest of your app.
When switching from SQLite to PostgreSQL, you only update the repository code, not the whole app.
Manual data access scatters database code everywhere.
Repository pattern centralizes data logic in one place.
This makes your Flask app easier to maintain and evolve.
Practice
Repository pattern in a Flask application?Solution
Step 1: Understand the role of repository pattern
The repository pattern is designed to separate how data is accessed from how it is used in the app logic.Step 2: Identify the correct purpose in Flask context
In Flask, this means keeping database queries inside repository classes, so the rest of the app doesn't need to know database details.Final Answer:
To separate data access logic from business logic -> Option DQuick Check:
Repository pattern = separation of concerns [OK]
- Thinking it speeds up server response
- Confusing it with authentication handling
- Assuming it creates frontend templates
Solution
Step 1: Check method signature in a class
Repository methods inside a class must haveselfas the first parameter.Step 2: Verify correct SQLAlchemy query syntax
To get all records, useUser.query.all(). Other options use incorrect method names or missself.Final Answer:
def get_all_users(self): return User.query.all() -> Option BQuick Check:
Method with self + User.query.all() = correct [OK]
- Omitting self parameter in method
- Using wrong query method like User.all()
- Using User.query.get_all() which doesn't exist
def get_user_by_id(self, user_id):
return User.query.filter_by(id=user_id).first()What will
repo.get_user_by_id(5) return if no user with ID 5 exists?Solution
Step 1: Understand SQLAlchemy filter_by().first() behavior
Thefirst()method returns the first matching record orNoneif no match is found.Step 2: Apply to user_id 5 with no matching user
Since no user with ID 5 exists, the method returnsNone, not a list or exception.Final Answer:
None -> Option AQuick Check:
filter_by().first() returns None if no match [OK]
- Expecting an empty list instead of None
- Thinking it raises an exception
- Assuming it returns a dummy User object
def add_user(self, user):
db.session.add(user)
db.session.commitWhat is the error here?
Solution
Step 1: Check method calls on db.session
Thecommitmethod must be called with parentheses:commit().Step 2: Identify the missing parentheses error
Without parentheses,commitis just a reference, so changes are not saved.Final Answer:
Missing parentheses after commit method call -> Option AQuick Check:
commit() needs parentheses to execute [OK]
- Forgetting parentheses on commit
- Using db.add instead of db.session.add
- Calling commit before add
Solution
Step 1: Understand filtering by string suffix in SQLAlchemy
To filter emails ending with a string, usefilter(User.email.endswith(...)).Step 2: Check each option's correctness
def get_example_users(self): return User.query.filter(User.email.endswith('@example.com')).all() usesendswithandall()to get all matches, which is correct. def get_example_users(self): return User.query.filter_by(email='@example.com').all() usesfilter_bywith exact match, not suffix. def get_example_users(self): return User.query.filter(User.email.contains('@example.com')).first() usescontainsbut returns only first match. def get_example_users(self): return User.query.filter(User.email == '@example.com').all() uses equality check, not suffix.Final Answer:
def get_example_users(self): return User.query.filter(User.email.endswith('@example.com')).all() -> Option CQuick Check:
Use endswith() + all() for suffix filtering [OK]
- Using filter_by for partial matches
- Using contains but returning only first result
- Using equality operator instead of endswith
Ready to prove it?
Pass the test and this pattern moves unknown
