SQLAlchemy:查询没有直接关系的所有对象

时间:2017-12-21 06:11:54

标签: python orm sqlalchemy

我是ORM的新手,所以任何评论都表示赞赏。使用以下代码,我尝试获取与某些分类相关的所有联系人

Base = declarative_base()

contact_category_association_table = Table('contact_category_association', Base.metadata,
    Column('contact_id', Integer, ForeignKey('contacts.id')),
    Column('category_id', Integer, ForeignKey('contact_categories.id'))
)

class Contact(Base):
    __tablename__ = 'contacts'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    categories = relationship('ContactCategory', secondary=contact_category_association_table)


class ContactCategory(Base):
    __tablename__ = 'contact_categories'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    contacts = relationship('Contact', secondary=contact_category_association_table)
    classification_id = Column(Integer, ForeignKey('contact_classification.id'))
    classification = relationship('ContactClassification', back_populates='categories')


class ContactClassification(Base):
    __tablename__ = 'contact_classification'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    categories = relationship('ContactCategory', back_populates='classification')

使用以下SQL我设法得到一个接近我需要的结果。但是,我无法使用sqlalchemy ORM进行翻译。

select * from contacts c
join contact_categories cc,  contact_category_association cca, contact_classification ccl
where c.id = cca.contact_id and cc.id = cca.category_id and ccl.id = cc.classification_id;

我正在寻找的结果是一个dict对象。密钥将是分类的ID或名称。该值将是联系人列表。

更新

详细说明。每个联系人按其职业(ContactCategory)分类。联系人和类别之间的关系是多对多的。类别被分类(或分组)到类中。每个类别可以属于1个类(一对多)。以下是示例数据:

Contacts
1|Alpha
2|Bear
3|Cel
4|Deer
5|Elk

ContactCategory
1|Builder|2
2|Carpenter|2
3|Metal Works|2
4|Networking & Cabling|1
5|Gypsum|2

ContactClassification
1|Electronics
2|Building & Decor
3|Plumping & Piping

contact_category_association
1|1
1|2
2|2
3|4
4|2
4|5
5|5

使用ORM,我希望得到以下结果(作为python dict对象):

result = {
'Electronics': [<Cel>],
'Building & Decor': [<Alpha>, <Bear>, <Deer>, <Elk>],
'Plumping & Piping': []
}

其中键是类名,值是属于每个类的联系人列表(通过类别)。

如果表名混乱,我很抱歉。我在重构项目的重构过程中,没有时间重命名表。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

不完全是您的想法,因为不会包含空结果,但通常您可以在Python中查询contact_classification.name, contacts.*元组和组:

from collections import defaultdict

query = session.query(ContactClassification.name, Contact).\
    join('categories', 'contacts')

result = defaultdict(list)

for klass, contact in query:
    result[klass].append(contact)