sqlalchemy查询中的自定义方法

时间:2020-07-10 12:13:46

标签: python sqlalchemy

我想要的是从ShipProperties表中获取实体,并从ShipPropertiesVisibility表中提取信息,以获取简单的实体can_seecan_edit,分别说明用户是否可以查看或编辑该属性

基本上是这样的(我试图在同一个模块中使用python方法),除了语法上不能正常工作:

def get_properties(ship_internal_id, user_id, company_id):
    ship_properties = db.session.query(ShipProperties, 
            _can_see(ShipPropertiesVisibility.visible 
                    if ShipPropertiesVisibility is not None else None) \
                .label("can_see"), 
            _can_edit(ShipAccess.view_only, ShipPropertiesVisibility.editable 
                    if ShipPropertiesVisibility is not None else None) \
                .label("can_edit"))
            ...
    return ship_properties

def _can_see(visible):
    return visible is None or visible is True

def _can_edit(ship_access_view_only, editable):
    return ship_access_view_only is False \
        and (editable is None or editable is True)

我还尝试了以下操作,因为我的_can_see_can_edit函数只是andor运算符的简单组合:

ship_properties = db.session.query(ShipProperties, 
        func.or_(ShipPropertiesVisibility.visible == None,
                ShipPropertiesVisibility.visible == True) \
            .label("can_see"), 
        func.and_(ShipAccess.view_only == False,
                or_(ShipPropertiesVisibility.editable == None,
                    ShipPropertiesVisibility.editable == True)) \
            .label("can_edit"))\
        ...

但是与此同时,我得到了以下错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "or"
LINE 1: ...groups, properties.private AS properties_private, or(ship_pr...

我也研究了hybrid properties and methods,但是由于ShipPropertiesVisibility实体可以为None(意味着该属性可以被用户看到和编辑),因此我认为这些方法不会起作用,在这种情况下,我不会相信我可以调用方法或属性。如果我错了,请纠正我。

我是否已接近解决方案,只是缺少正确的语法,或者这是思维中的重大错误,所以我宁愿研究例如将sqlalchemy结果转换为视图模型,还是其他?

1 个答案:

答案 0 :(得分:0)

通过使用通用的.op()方法,我找到了使用布尔sql运算符的方法。

ship_properties = db.session.query(ShipProperties, Properties, 
        ((ShipPropertiesVisibility.visible == None) \
            .op("OR")(ShipPropertiesVisibility.visible)) \
            .label("can_see"),
        (ShipAccess.view_only == False)
            .op("AND")((ShipPropertiesVisibility.editable == None) \
                .op("OR")(ShipPropertiesVisibility.editable)) \
            .label("can_edit"))\
相关问题