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

Posted

技术标签:

【中文标题】SQLAlchemy:查询所有没有直接关系的对象【英文标题】:SQLAlchemy: querying all objects with no direct relationship 【发布时间】:2017-12-21 06:11:54 【问题描述】:

我是 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】:

不完全是您的想法,因为不会包含空结果,但通常您可以在 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查询

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

了解 SQLAlchemy ForeignKey 关系查询结果

SQLAlchemy

SqlAlchemy ORM