基于排除关系中的项的Sqlalchemy查询

2024-09-28 21:51:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个PartyOrganiser(s)的表,一个Contact(s)的表和一个组织的Party(s)的表。在

PartyOrganiserParty是一对多。
PartyOrganiser到{}是一对多
PartytoContact多对多,带有一个关联表。

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')

主要问题:

从语法上讲,对于一个特定的聚会,我想获取一个与该党组织者相关但尚未参加该聚会的联系人的列表。一、 e.称他们为潜在的与会者,我希望以下是SQLalchemy查询风格的解决方案:

^{pr2}$

子问题:

此配置在PartyOrganiserPartyContact之间有一个固有的3向约束:只有当聚会和与会者共享一个聚会组织者时,才能将其关联起来。一、 e.PartyOrganiser1的联系人不能是PartyOrganiser2组织的Party2的参与者。在我看来,这是不明显的,在上述格式的要求。事实上我不相信。我该如何实现这个约束呢?在


Tags: iddbmodelpartybackcontactcolumninteger
1条回答
网友
1楼 · 发布于 2024-09-28 21:51:04

您可以使用联接表上的NOT EXISTS构造查询关系中排除的项。在

@property
def potential_attendees(self):
    sq = db.session.query(contact_party_ass_tab.columns.contact_id).subquery()
    return db.session.query(Contact).filter(
            Contact.party_organiser_id==self.party_organiser_id,
            ~exists().where(sq.c.contact_id==Contact.id)
        ).all()

至于您的另一个问题,您可以通过为添加属性级验证器将该约束施加到ORM级别聚会。与会者以及联系意向方并确保所有添加到这些列表中的新项目都有一个匹配的party_Organizer_id。这是完整的代码

^{pr2}$

输出(检查上面代码最后一行抛出的异常):

In [1]: from exclusion_query import *
/home/surya/Envs/inkmonk/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
Potential attendees of org1_party1  [Organiser1's contact 2, Organiser1's contact 3, Organiser1's contact 4]
Attempting to add a contact of a different organiser. Will throw exception
                                     -
AssertionError                            Traceback (most recent call last)
<ipython-input-1-4380704ace46> in <module>()
  > 1 from exclusion_query import *

相关问题 更多 >