I'm working with Flask-SQLAlchemy to create a many-to-many relationship using Association Objects and association_proxy
, but I'm running into an issue: When I use association_proxy
, I can set it up such that when I append a new instance to one side of the relationship, the Association Object will be created, but if I attempt to add an instance from the other side of the relationship, the Association Object constructor won't be passed the correct instance.
Here's a simplified example where Club
has many People
, and People
have many Club
, and the Association Object is a Membership
:
class Club(db.Model):
__tablename__ = 'clubs'
id = db.Column(db.Integer, db.Sequence('clubs_id_seq'), autoincrement=True, primary_key=True)
name = db.Column(db.String(255))
memberships = db.relationship('Membership', backref='club')
members = association_proxy('memberships', 'club') # Can I pass a Person instance to Membership here?
created_at = db.Column('created_at', db.DateTime, default=datetime.datetime.now())
def __init__(self, name):
self.name = name
class Person(db.Model):
__tablename__ = 'people'
id = db.Column(db.Integer, db.Sequence('people_id_seq'), autoincrement=True, primary_key=True)
name = db.Column(db.String(255))
memberships = db.relationship('Membership', backref='person')
clubs = association_proxy('memberships', 'club')
created_at = db.Column('created_at', db.DateTime, default=datetime.datetime.now())
def __init__(self, name):
self.name = name
class Membership(db.Model):
__tablename__ = 'memberships'
person_id = db.Column('person_id', db.Integer, db.ForeignKey('people.id'), primary_key=True)
club_id = db.Column('club_id', db.Integer, db.ForeignKey('clubs.id'), primary_key=True)
club = db.relationship('Club', backref='membership')
joined_at = db.Column('joined_at', db.DateTime, default=datetime.datetime.now())
def __init__(self, club):
self.club = club
I'm using association_proxy
because more than just the connection between Club
and Person
is important; I also want to be able to retrieve the joined_at
property of the Membership
if needed. In most cases, though, I only will query and append to .members
of a Club
or .clubs
of a Person
. In this example, I can create a new Membership
by calling person_instance.clubs.append(club_instance)
, but since the constructor of Membership
can only take a single argument, how can I call club_instance.members.append(person_instance)
if I were to work backwards? It seems lame that I could potentially iterate over club_instance.members
, but have to remember not to append()
. Am I missing something?