我有兩個燒瓶SQLAlchemy的模型與一個簡單的一對多的關係,如下面的最小例如:SQLAlchemy的:混合的表達與關係
class School(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
address = db.Column(db.String(30))
class Teacher(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
id_school = db.Column(db.Integer, db.ForeignKey(School.id))
school = relationship('School', backref='teachers')
然後我的混合屬性添加到教師使用該關係,如:當我使用它作爲teacher_instance.school_name
@hybrid_property
def school_name(self):
return self.school.name
;財產工作得很好。不過,我也想提出查詢,如Teacher.query.filter(Teacher.school_name == 'x')
,但給我一個錯誤:
`AttributeError: Neither 'InstrumentedAttribute' object nor
'Comparator' object has an attribute 'school_name'`.
繼SQLAlchemy的文檔,我添加了一個簡單的混合表達式,如下所示:
@school_name.expression
def school_name(cls):
return School.name
然而,當我再次嘗試相同的查詢時,它會生成一個不含連接子句的SQL查詢,因此我在School中獲得所有可用的行,而不僅僅是那些與Teacher中的外鍵匹配的行。
從SQLAlchemy的文檔,我意識到,表達希望在加入已經存在的上下文,所以我試圖再次查詢爲:
Teacher.query.join(School).filter(Teacher.school_name == 'x')
而且,實際工作,但它違背了目的如果我需要學校模型的知識來獲得那個,首先嚐試在那裏獲得語法糖。我希望有一種方法可以在表達式中加入,但我無法在任何地方找到它。該文檔有一個例子,表達式返回直接使用select()
構建的子查詢,但即使這樣也不適用於我。
任何想法?
UPDATE
後伊布的回答下面,我用的是聯想代理的建議和它的作品,但我也得到了好奇與評論,它應該與select()
子查詢工作,並試圖找出我做錯了。我最初的嘗試是:
@school_name.expression
def school_name(cls):
return select(School.name).where(cls.id_school == School.id).as_scalar()
而事實證明,給我一個錯誤,因爲我錯過了select()中的列表。下面的代碼工作正常:
@school_name.expression
def school_name(cls):
return select([School.name]).where(cls.id_school == School.id).as_scalar()
這簡直太可笑了。非常感謝。 –
你對'select()'是對的。我的錯。我爲這個問題添加了一個更新。 –