当前位置: 首页 > 面试题库 >

SQLAlchemy:具有关系的混合表达式

有德业
2023-03-14
问题内容

我有两个具有简单的一对多关系的Flask-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')

然后,我向使用该关系的老师添加一个混合属性,如下所示:

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

当我将其用作时,该属性可以正常工作teacher_instance.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

但是,当我再次尝试相同的查询时,它会生成一个不带join子句的SQL查询,因此我得到了School中所有可用的行,而不仅仅是匹配Teacher中外键的行。

从SQLAlchemy文档中,我意识到该表达式需要一个已经存在联接的上下文,因此我再次尝试查询该查询,如下所示:

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

这确实有效,但是如果我需要了解School模型来获取语法糖,那么它首先会挫败尝试在其中获取语法糖的目的。我希望有一种方法可以使该表达式加入表达式,但是我在任何地方都找不到它。文档中有一个示例,该表达式返回直接使用构建的子查询select(),但即使这样对我也不起作用。

有任何想法吗?

更新

在下面的Eevee回答之后,我按建议使用了关联代理,它可以工作,但是我也对它应该与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()

问题答案:

对于这样的简单情况,一种更简单的方法是关联代理:

class Teacher(db.Model):
    school_name = associationproxy('school', 'name')

这支持==自动查询(至少使用)。

我很好奇混合select()示例对您不起作用,因为这是在混合中解决此问题的最简单方法。并且为了完成起见,您还可以使用转换器直接修改查询,而不是子查询。



 类似资料:
  • 问题内容: 我有一个简单的Author-Books模型,找不到将firstName和lastName用作复合键并在关系中使用它的方法。有任何想法吗? 问题答案: 问题在于您已将每个相关列分别定义为外键,如果这不是您想要的,那么您当然需要一个复合外键。Sqlalchemy通过说(以一种不太清楚的方式)对此做出响应,即无法猜测要使用哪个外键(或)。 声明复合外键的解决方案在声明性上有点笨拙,但仍然很明

  • 调用关系字段时是否可以在表单类型中使用集合? 以下是我想做的: 我和你有关系 我通过以下方式设置表单类型: 候选类型 分区学校型 因此,我在这里面临两个问题: >

  • 我有一个名为的实体,它与另一个实体有关系,该实体可以为null。这两个实体如下: 项目 类别 现在,我必须选择具有类似于搜索词的名称、代码或类别名称的项,对此我尝试了以下查询:

  • 当交换机分支调用void返回类型的方法时,有没有办法强制对所有枚举值进行彻底检查?仅仅为了诱使编译器要求穷尽性而对产量进行硬编码是非常丑陋的。 这是我当前的模式(handle方法具有void返回类型) 我想使用表达式的原因是在添加新枚举值但未处理时出现编译错误。

  • 问题内容: 我们有一个带有父子关系的表,希望对它进行排序。排序标准是这样的,以便在遍历结果时,与父ID匹配的行应该已经存在: 问题在于两个密钥都是字符串,因此按ID或PARENT_ID排序将无法解决问题。 问题答案: 对于Oracle,使用分层查询:

  • 我有2个表与一对多的关系如下: 我的实体类和hbm配置如下: AuditDetail.java 审核详细信息。hbm。xml AuditParameter。Java语言 AuditParameter。hbm。xml 我的hql查询如下: 但当我执行此查询时,它会给我以下错误: ORA-00936:缺少表达式 以下是我的查询触发的控制台输出。 根据这个输出,我们可以看到Hibernate没有为a.a

  • 2-查询id为1的人的所有地址,2我想: 好的方法是什么?

  • 问题内容: 我在线路42和43的误差:, 未处理的异常类型InterruptedException的 。如果我尝试快速修复,它将使用catch Exception 创建try catch ,它将具有相同的错误,并且将尝试以相同的方式修复它,并继续用try catch包围它。 问题答案: 您已创建一个函数接口,该函数接口的方法声明为引发,这是一个已检查的异常。但是,你叫一个lambda表达式作为参数