SQLAlchemy: expressão híbrida com relacionamento

Eu tenho dois modelos Flask-SQLAlchemy com um simples relacionamento um-para-muitos, como o exemplo mínimo abaixo:

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')

Então eu adiciono uma propriedade híbrida ao professor que usa o relacionamento, como:

@hybrid_property
def school_name(self):
    return self.school.name

E essa propriedade funciona bem quando eu a uso comoteacher_instance.school_name. No entanto, eu também gostaria de fazer perguntas comoTeacher.query.filter(Teacher.school_name == 'x'), mas isso me dá um erro:

`AttributeError: Neither 'InstrumentedAttribute' object nor 
'Comparator' object has an attribute 'school_name'`. 

Seguindo a documentação do SQLAlchemy, adicionei uma expressão híbrida simples, como a seguinte:

@school_name.expression
def school_name(cls):
    return School.name

No entanto, quando tento a mesma consulta novamente, ela gera uma consulta SQL sem a cláusula join, portanto, obtenho todas as linhas disponíveis na Escola, não apenas aquelas que correspondem à chave estrangeira no Teacher.

Da documentação do SQLAlchemy eu percebi que a expressão espera um contexto onde a junção já está presente, então eu tentei a consulta novamente como:

Teacher.query.join(School).filter(Teacher.school_name == 'x')

E isso realmente funciona, mas acaba com o propósito de tentar obter o açúcar sintático em primeiro lugar, se eu precisar de conhecimento do modelo da escola para conseguir isso. Eu espero que haja uma maneira de conseguir isso na expressão, mas não consegui encontrá-lo em lugar nenhum. A documentação tem um exemplo com a expressão retornando uma subconsulta criada diretamente com oselect(), mas mesmo isso não funcionou para mim.

Alguma ideia?

ATUALIZAR

Após a resposta de Eevee abaixo, usei o proxy de associação como sugerido e funciona, mas também fiquei curioso com o comentário de que deveria funcionar com oselect() subconsulta e tentei descobrir o que fiz de errado. Minha tentativa original foi:

@school_name.expression
def school_name(cls):
    return select(School.name).where(cls.id_school == School.id).as_scalar()

E acontece que estava me dando um erro porque perdi a lista em select (). O código abaixo funciona bem:

@school_name.expression
def school_name(cls):
    return select([School.name]).where(cls.id_school == School.id).as_scalar()