有一个与类标记有“有很多”关系的类运行。我需要能够基于标记的函数(tag_collection)过滤运行。
下面是我的代码片段。在这种情况下,我使用的是自动驾驶,但我不认为这太重要了。
Base = automap_base()
class Run(Base):
__tablename__ = 'runs'
macro_id = Column(ForeignKey('macros.id'))
@hybrid_property
def tag_count(self):
return(len(self.tag_collection))
@hybrid_property
def default_region(self):
return(reduce(lambda memo, t: memo or t.name == "region" and t.value == "default", self.tag_collection, False))
@default_region.expression
def default_region(cls):
# how do I do the query here?
class Tag(Base):
__tablename__ = 'tags'
run_id = Column(ForeignKey('runs.id')) 如果我得到一个运行实例,我可以使用default_region属性,但是当我运行一个查询并尝试使用default_region属性进行筛选时,我要么在@hybird_property修饰的default_region方法中传递Run类(作为self),要么在@default_region.expression修饰的default_region方法中结束,后者也接收Run类。
示例查询:
session.query(Run).filter(Run.default_region == True).all()我认为我需要在@default_region.expression修饰的default_region方法中执行一个查询,但是我不知道如何获得会话的句柄。我知道Session.object_session(someobject),但我认为someobject应该是orm类的实例,而不是类本身。
我认为我的过滤方法完全错了,或者我需要在@default_region.expression修饰的default_region方法中获得会话对象的句柄。
有更好的方法来完成这个过滤吗?
如何在@default_region.expression修饰的default_region方法中获取会话?
发布于 2018-05-27 15:00:29
在我看来,这是一个http://docs.sqlalchemy.org/en/latest/orm/extensions/hybrid.html#correlated-subquery-relationship-hybrid。添加Run.default_region作为筛选器时,要更新要添加的查询
WHERE EXISTS (
SELECT 1 FROM tags
WHERE run_id = runs.id
AND name = "region"
AND value = "default")使用 function将其作为表达式返回
from sqlalchemy.sql import exists, and_
@default_region.expression
def default_region(cls):
return exists([1]).where(and_(
Tag.run_id == cls.id,
Tag.name == 'region',
Tag.value == 'default'))请注意,您希望避免在这里使用== True或== False,没有必要!只需直接使用该属性:
session.query(Run).filter(Run.default_region).all()或者使用~否定:
session.query(Run).filter(~Run.default_region).all()通过为属性定义 method,您已经告诉SQLAlchemy在访问类上的属性时使用该方法,因此上下文始终是类。在不定义.exists (或.comparator)的情况下,Run.default_region会将default_region getter (用`@hybrid_property修饰的方法)调用为类方法,因此只有这样,该方法才能处理传入的实例或类。对于某些混合属性实现来说,这恰好取决于它们在上下文中使用属性的方式。
至于default_region实例属性的实现,我不会在那里使用reduce();使用 function
@hybrid_property
def default_region(self):
return any(
t.name == "region" and t.value == "default"
for t in self.tag_collection)当找到匹配时,any()停止对提供的生成器表达式进行迭代。
https://stackoverflow.com/questions/50553203
复制相似问题