Python SQLAlchemy/Elixir-查询以检查实体';s在多对多关系列表中的成员身份

Python SQLAlchemy/Elixir-查询以检查实体';s在多对多关系列表中的成员身份,python,sqlalchemy,many-to-many,python-elixir,Python,Sqlalchemy,Many To Many,Python Elixir,我正在尝试构造一个sqlalchemy查询,以获得麻省理工学院所有助理教授的名单。请注意,一门课程可以有多个助理教授 我试图做的大致相当于: uni_mit = University.get_by(name='MIT') s = select([Professor.name], and_(Professor.in_(Course.assistants), Course.university = uni_mit)) session.execut

我正在尝试构造一个sqlalchemy查询,以获得麻省理工学院所有助理教授的名单。请注意,一门课程可以有多个助理教授

我试图做的大致相当于:

uni_mit = University.get_by(name='MIT')
s = select([Professor.name],
           and_(Professor.in_(Course.assistants),
                Course.university = uni_mit))
session.execute(s)
这将不起作用,因为中的
仅为实体的字段定义,而不是为整个实体定义。。不能将
Professor.id.in.
用作课程助理是教授列表,而不是他们的id列表。我也尝试了
包含
,但也没有成功

我的长生不老药模型是:

class Course(Entity):
    id = Field(Integer, primary_key=True)
    assistants = ManyToMany('Professor', inverse='courses_assisted', ondelete='cascade')
    university = ManyToOne('University')
    ..

class Professor(Entity):
    id = Field(Integer, primary_key=True)
    name = Field(String(50), required=True)
    courses_assisted = ManyToMany('Course', inverse='assistants', ondelete='cascade')
    ..
如果我可以访问中间的多对多实体(条件是
和(interm_table.prof_id=Professor.id,interm_table.course=course.id)
,这将是微不足道的,但是SQLAlchemy显然对我隐藏了这个表

我正在使用Elixir0.7和SQLAlchemy 0.6


顺便说一句:这个问题不同于我需要对照所有满足条件的课程检查教授,而不是单一的静态课程。

你可以找到Elixir隐藏它的中间表,但请注意它使用完全限定的列名(例如,
\uu package\u path\u,带下划线\uu课程id
).为避免出现这种情况,请使用例如

class Course(Entity):
    ...
    assistants = ManyToMany('Professor', inverse='courses_assisted',
                            local_colname='course_id', remote_colname='prof_id',
                            ondelete='cascade')
然后您可以使用

rel = Course._descriptor.find_relationship('assistants')
assert rel
table = rel.table
并且可以使用
table.c.prof_id
等访问列

更新:当然,您可以在更高级别上执行此操作,但不能在单个查询中执行,因为SQLAlchemy尚不支持关系的
。例如,对于两个查询:

>>> mit_courses = set(Course.query.join(
... University).filter(University.name == 'MIT'))
>>> [p.name for p in Professor.query if set(
... p.courses_assisted).intersection(mit_courses)]
或者,或者:

>>> plist = [c.assistants for c in Course.query.join(
... University).filter(University.name == 'MIT')]
>>> [p.name for p in set(itertools.chain(*plist))]

第一步创建助理列表。第二步通过创建一个集合来展平列表列表并删除重复项。

隐藏辅助表的不是sqlalchemy;在vanilla sqlalchemy中,您需要命名和描述该表,但建议不要将其映射到类。由于Elix,会发生混淆ir.我更新了我的答案以回应您的评论。谢谢!解决方案将是简单明了的,但有点冗长。有没有一种方法可以在不访问中间表的情况下解决这个问题(例如,某种
包含
/
的语法我不知道)?毕竟,ORM旨在从数据存储方式中提取数据。。