I have a table of PartyOrganiser
(s), and a table of one's Contact
(s) and a table of one's organised Party
(s).
PartyOrganiser
to Party
is one-to-many.
PartyOrganiser
to Contact
is one-to-many.
Party
to Contact
is many-to-many, with an association table.
class PartyOrganiser(db.Model):
__tablename__ = 'party_organiser'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
parties = db.relationship("Party", back_populates='party_organiser')
contacts = db.relationship("Contacts", back_populates='party_organiser')
contact_party_ass_tab = db.Table('contact_party', db.Model.metadata,
db.Column('party_id', db.Integer, db.ForeignKey('party.id')),
db.Column('contact_id', db.Integer, db.ForeignKey('contact.id')))
class Party(db.Model):
__tablename__ = 'party'
id = db.Column(db.Integer, primary_key=True)
details = db.Column(db.String)
party_organiser_id = db.Column(db.Integer, db.ForeignKey('party_organiser.id'), nullable=False)
party_organiser = db.relationship("PartyOrganiser", back_populates="parties", uselist=False)
attendees = db.relationship("Contact", secondary=contact_party_ass_tab, back_populates='intended_parties')
class Contact(db.Model):
__tablename__ = 'contact'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
party_organiser_id = db.Column(db.Integer, db.ForeignKey('party_organiser.id'), nullable=False)
party_organiser = db.relationship("PartyOrganiser", back_populates="parties", uselist=False)
intended_parties = db.relationship("Contact", secondary=contact_party_ass_tab, back_populates='attendees')
Main Question:
Grammatically, for a specific party, I want to acquire a list of those contacts associated with the party's organiser that are not already attending the party. I.e. calling them potential_attendees, I would like the following as an SQLalchemy query style solution:
class Party(db.model):
...
@property
def potential_attendees(self):
# get all contacts for the right party_organiser
sub_query = Contact.query.filter(Contact.party_organiser_id == self.party_organiser_id)
# then eliminate those that are already attendees to this party..
return sub_query.difference(self.attendees) # <- pseudocode
Sub question:
This configuration has an inherent 3 way constraint between PartyOrganiser
, Party
and Contact
: parties and attendees can only be associated if they share a party_organiser. I.e. None of PartyOrganiser1's contacts can be attendees to Party2 organised by PartyOrganiser2. It is not obvious to me that this is constrained as required in the above format. In fact I believe it isn't. How would I implement this constraint?