Bird
Raised Fist0
Flaskframework~5 mins

Repository pattern for data access in Flask

Choose your learning style10 modes available
Introduction

The repository pattern helps organize how your app talks to the database. It keeps data access code separate and easy to manage.

When you want to keep your database code clean and separate from your app logic.
When you plan to change the database later and want to avoid rewriting lots of code.
When you want to write tests without needing a real database.
When multiple parts of your app need to access data in a consistent way.
Syntax
Flask
class Repository:
    def __init__(self, db_session):
        self.db_session = db_session

    def add(self, entity):
        self.db_session.add(entity)
        self.db_session.commit()

    def get(self, entity_id):
        return self.db_session.query(Entity).get(entity_id)

    def list(self):
        return self.db_session.query(Entity).all()

The Repository class wraps database operations.

Use methods like add, get, and list to work with data.

Examples
This example shows a repository for users, with methods to add and get users.
Flask
class UserRepository:
    def __init__(self, db_session):
        self.db_session = db_session

    def add_user(self, user):
        self.db_session.add(user)
        self.db_session.commit()

    def get_user(self, user_id):
        return self.db_session.query(User).get(user_id)
This example lists all products using the repository pattern.
Flask
class ProductRepository:
    def __init__(self, db_session):
        self.db_session = db_session

    def list_products(self):
        return self.db_session.query(Product).all()
Sample Program

This Flask app uses SQLAlchemy and the repository pattern to add and list users. It keeps database code inside UserRepository.

Flask
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))

class UserRepository:
    def __init__(self, db_session):
        self.db_session = db_session

    def add_user(self, user):
        self.db_session.add(user)
        self.db_session.commit()

    def get_user(self, user_id):
        return self.db_session.query(User).get(user_id)

    def list_users(self):
        return self.db_session.query(User).all()

with app.app_context():
    db.create_all()
    repo = UserRepository(db.session)

    user1 = User(name='Alice')
    user2 = User(name='Bob')

    repo.add_user(user1)
    repo.add_user(user2)

    all_users = repo.list_users()
    for user in all_users:
        print(f'User {user.id}: {user.name}')
OutputSuccess
Important Notes

Using the repository pattern makes your code easier to test and maintain.

Remember to commit changes in the repository methods to save data.

Keep repository methods focused on one task for clarity.

Summary

The repository pattern separates data access from app logic.

It helps keep your code clean and easier to change later.

Use repository classes to add, get, and list data in a simple way.

Practice

(1/5)
1. What is the main purpose of using the Repository pattern in a Flask application?
easy
A. To create HTML templates for the frontend
B. To speed up the Flask server response time
C. To handle user authentication automatically
D. To separate data access logic from business logic

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    To separate data access logic from business logic -> Option D
  4. Quick Check:

    Repository pattern = separation of concerns [OK]
Hint: Repository pattern means separate data from app logic [OK]
Common Mistakes:
  • Thinking it speeds up server response
  • Confusing it with authentication handling
  • Assuming it creates frontend templates
2. Which of the following is the correct way to define a repository class method to get all users in Flask?
easy
A. def get_all_users(): return User.query.all()
B. def get_all_users(self): return User.query.all()
C. def get_all_users(self): return User.all()
D. def get_all_users(self): return User.query.get_all()

Solution

  1. Step 1: Check method signature in a class

    Repository methods inside a class must have self as the first parameter.
  2. Step 2: Verify correct SQLAlchemy query syntax

    To get all records, use User.query.all(). Other options use incorrect method names or miss self.
  3. Final Answer:

    def get_all_users(self): return User.query.all() -> Option B
  4. Quick Check:

    Method with self + User.query.all() = correct [OK]
Hint: Repository methods need self and correct query syntax [OK]
Common Mistakes:
  • Omitting self parameter in method
  • Using wrong query method like User.all()
  • Using User.query.get_all() which doesn't exist
3. Given this repository method in Flask:
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?
medium
A. None
B. Raises an exception
C. An empty list []
D. A User object with id 5

Solution

  1. Step 1: Understand SQLAlchemy filter_by().first() behavior

    The first() method returns the first matching record or None if no match is found.
  2. Step 2: Apply to user_id 5 with no matching user

    Since no user with ID 5 exists, the method returns None, not a list or exception.
  3. Final Answer:

    None -> Option A
  4. Quick Check:

    filter_by().first() returns None if no match [OK]
Hint: filter_by().first() returns None if no record found [OK]
Common Mistakes:
  • Expecting an empty list instead of None
  • Thinking it raises an exception
  • Assuming it returns a dummy User object
4. You wrote this repository method:
def add_user(self, user):
    db.session.add(user)
    db.session.commit

What is the error here?
medium
A. Missing parentheses after commit method call
B. db.session.add should be db.add
C. user parameter should be a dictionary, not an object
D. commit should be called before add

Solution

  1. Step 1: Check method calls on db.session

    The commit method must be called with parentheses: commit().
  2. Step 2: Identify the missing parentheses error

    Without parentheses, commit is just a reference, so changes are not saved.
  3. Final Answer:

    Missing parentheses after commit method call -> Option A
  4. Quick Check:

    commit() needs parentheses to execute [OK]
Hint: Always call commit() with parentheses [OK]
Common Mistakes:
  • Forgetting parentheses on commit
  • Using db.add instead of db.session.add
  • Calling commit before add
5. You want to implement a repository method that returns all users whose email ends with '@example.com'. Which of these is the best way to write it using SQLAlchemy in Flask?
hard
A. def get_example_users(self): return User.query.filter(User.email.contains('@example.com')).first()
B. def get_example_users(self): return User.query.filter_by(email='@example.com').all()
C. def get_example_users(self): return User.query.filter(User.email.endswith('@example.com')).all()
D. def get_example_users(self): return User.query.filter(User.email == '@example.com').all()

Solution

  1. Step 1: Understand filtering by string suffix in SQLAlchemy

    To filter emails ending with a string, use filter(User.email.endswith(...)).
  2. Step 2: Check each option's correctness

    def get_example_users(self): return User.query.filter(User.email.endswith('@example.com')).all() uses endswith and all() to get all matches, which is correct. def get_example_users(self): return User.query.filter_by(email='@example.com').all() uses filter_by with exact match, not suffix. def get_example_users(self): return User.query.filter(User.email.contains('@example.com')).first() uses contains but returns only first match. def get_example_users(self): return User.query.filter(User.email == '@example.com').all() uses equality check, not suffix.
  3. Final Answer:

    def get_example_users(self): return User.query.filter(User.email.endswith('@example.com')).all() -> Option C
  4. Quick Check:

    Use endswith() + all() for suffix filtering [OK]
Hint: Use endswith() for suffix filtering in queries [OK]
Common Mistakes:
  • Using filter_by for partial matches
  • Using contains but returning only first result
  • Using equality operator instead of endswith
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard