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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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': []
}

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

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

感谢您的帮助。

答案

不完全是你的想法,因为不会包含空结果,但一般来说你可以在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)

以上是关于SQLAlchemy:查询没有直接关系的所有对象的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy 关系错误:对象没有属性“c”

SQLAlchemy-对象关系教程ORM查询

Django ORM和SQLAlchemy类比

SQLAlchemy:直接从一对多关系中删除对象,而不使用 session.delete()

SQLAlchemy_定义(一对一/一对多/多对多)关系

了解 SQLAlchemy ForeignKey 关系查询结果