Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`

Modeling relationships between tables is essential for representing data’s real-world connections. Flask-SQLAlchemy provides two constructs to manage relationships: db.relationship and association_proxy.

There are three types of database relationship…


This content originally appeared on DEV Community and was authored by Riko

Modeling relationships between tables is essential for representing data's real-world connections. Flask-SQLAlchemy provides two constructs to manage relationships: db.relationship and association_proxy.

There are three types of database relationships:

  1. One-to-many: One parent, many children
  2. One-to-one: One parent, one child
  3. Many-to-many: Many parents relate to many children

In this blog, I'll demonstrate how db.relationship and association_proxy are used in a database that has Meditations, Users, and Meditation Sessions.

  1. A user has many meditations through meditation sessions
  2. A meditation session has one meditation and one user
  3. A meditation has many users through meditation sessions

Here is the Python code with each class model and their relationships, including foreign key columns and serialize rules to prevent recursion:

class Meditation(db.Model, SerializerMixin):
    __tablename__ = "meditations"


    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    duration = db.Column(db.Integer)
    instructions = db.Column(db.String)

    meditation_sessions = db.relationship('MeditationSession', back_populates='meditation', cascade='all, delete-orphan')

    users = association_proxy('meditation_sessions', 'user', creator=lambda user_obj: MeditationSession(user=user_obj))

    serialize_rules = ('-users.meditations', '-meditation_sessions.meditation',)


class User(db.Model, SerializerMixin):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, unique=True, nullable=False)
    _password_hash = db.Column(db.String)

    meditation_sessions = db.relationship('MeditationSession', back_populates='user', cascade='all, delete-orphan')

    meditations = association_proxy('meditation_sessions', 'meditation', creator=lambda meditation_obj: MeditationSession(meditation=meditation_obj))

    serialize_rules = ('-meditations.users', '-meditation_sessions.user')

class MeditationSession(db.Model, SerializerMixin):
    __tablename__ = "meditation_sessions"

    id = db.Column(db.Integer, primary_key=True)
    completed_duration = db.Column(db.Integer)
    rating = db.Column(db.Integer)
    session_note = db.Column(db.String)

    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    meditation_id = db.Column(db.Integer, db.ForeignKey('meditations.id'))

    user = db.relationship('User', back_populates='meditation_sessions')
    meditation = db.relationship('Meditation', back_populates='meditation_sessions')

    serialize_rules = ('-meditation.meditation_sessions', '-user.meditation_sessions')

db.relationship: establishing bi-directional relationships

db.relationship defines how tables or models relate to one another in Python objects. It works alongside foreign keys to create clear links and enable convenient querying and data manipulation.

Let's break down the relationship between a User and Meditation Session.

For a session, the relationship to a user is:
user = db.relationship('User', back_populates='meditation_sessions')

  • Since a meditation session has only one user, the name of the property is singular
  • The first argument passed to db.relationship is the target model class name (User)
  • back_populates is the name of the reciprocal relationship property on the User model (meditation_sessions)

Inversely, a user's relationship to a meditation session is:
meditation_sessions = db.relationship('MeditationSession', back_populates='user', cascade='all, delete-orphan')

  • Since a user can have many meditation sessions, the name of the property is plural
  • The first argument is the target model class name (MeditationSession)
  • And back_populates points back to the user relationship property we defined in Meditation Session, enabling a bidirectional link between the two models
  • cascade specifies how SQLAlchemy will handle child objects if the parent object were to disappear. There are several options that can be passed:
    • all is a combination of save-update, merge, and delete, meaning the child meditation sessions will be added to the database session, merged if the session contains duplicate objects, and deleted if the parent object is deleted
    • delete-orphan will delete a child if it is disassociated from its parent, meaning if a meditation session is removed from user.meditation_sessions, the meditation session will be deleted

association_proxy: establishing Many-to-Many relationships

association_proxy is a construct that allows a class to reach across an intermediary class in a many-to-many relationship. In our model, a user can have many meditations through meditation sessions, and a meditation can have many users through meditation sessions. Meditation Session is the intermediary class between Users and Meditations.

Let's break down the association proxy between User and Meditation.

For a user, the association to meditation is:
meditations = association_proxy('meditation_sessions', 'meditation', creator=lambda meditation_obj: MeditationSession(meditation=meditation_obj))

  • Since this is a many-to-many relationship, the property name is plural (meditations)
  • The first argument passed to association_proxy specifies the relationship property we defined above with db.relationship and intend to use as a connector (meditation_sessions)
  • The second argument (meditation) indicates the name of the model we're connecting to
  • The creator parameter takes a function (an anonymous lambda in this case), which accepts an object of the other independent class and returns the corresponding object of the connecting class that made the connection possible
    • The lambda function creates a new intermediary MeditationSession object when a Meditation is added to the meditations association proxy
    • meditation_obj is an instance of the Meditation model passed in by the association_proxy
    • MeditationSession(meditation=meditation_obj) creates a new MeditationSession object and sets its meditation relationship to that meditation_obj
    • This new MeditationSession instance acts as the link or bridge between the User and the Meditation


This content originally appeared on DEV Community and was authored by Riko


Print Share Comment Cite Upload Translate Updates
APA

Riko | Sciencx (2025-10-25T14:24:34+00:00) Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`. Retrieved from https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/

MLA
" » Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`." Riko | Sciencx - Saturday October 25, 2025, https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/
HARVARD
Riko | Sciencx Saturday October 25, 2025 » Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`., viewed ,<https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/>
VANCOUVER
Riko | Sciencx - » Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/
CHICAGO
" » Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`." Riko | Sciencx - Accessed . https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/
IEEE
" » Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy`." Riko | Sciencx [Online]. Available: https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/. [Accessed: ]
rf:citation
» Understanding Database Relationships in Flask-SQLAlchemy: `db.relationship` and `association_proxy` | Riko | Sciencx | https://www.scien.cx/2025/10/25/understanding-database-relationships-in-flask-sqlalchemy-db-relationship-and-association_proxy/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.