Python SQLAlchemy/Elixir-查询以检查实体';s在多对多关系列表中的成员身份
我正在尝试构造一个sqlalchemy查询,以获得麻省理工学院所有助理教授的名单。请注意,一门课程可以有多个助理教授 我试图做的大致相当于: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
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旨在从数据存储方式中提取数据。。