从用户输入动态生成sqlalchemy过滤器(在本例中为Jqgrid)

时间:2014-02-09 14:43:23

标签: python jqgrid sqlalchemy

请考虑以下示例。

{"groupOp":"AND","rules":[{"field":"Rate","op":"eq","data":"6"}],"groups":[{"groupOp":"OR","rules":[{"field":"Code","op":"eq","data":"abc"},{"field":"Name","op":"eq","data":"fd"}],"groups":[]}]}
  1. 分析,我需要递归生成每个子句的二进制表达式
  2. 然后使用“and_”或“or_”函数组合结果。
  3. 但是我仍然坚持第一点。

    关于如何实现它的任何指示?

1 个答案:

答案 0 :(得分:2)

我假设“AND - >(规则),(群组)”的含义“意味着你想要AND(rule1,rule2,rule3 ... group1,group2,group3 ......)。我不确定那会怎么样。

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Thing(Base):
    __tablename__ = 'thing'
    id = Column(Integer, primary_key=True)
    Rate = Column(Integer)
    Code = Column(String)
    Name = Column(String)

rules = {
    "groupOp": "AND",
    "rules":[
        {
            "field":"Rate",
            "op":"eq",
            "data":"6"
        }
    ],
    "groups":[
        {"groupOp":"OR",
        "rules":[
            {"field":"Code", "op":"eq", "data":"abc"},
            {"field":"Name","op":"eq","data":"fd"}
        ],
        "groups":[]
    }
]}


from sqlalchemy import and_, or_
from operator import eq
lookup = {
    "AND": and_,
    "OR": or_,
    "eq": eq
}

def visit_rule(rules):
    fn = lookup[rules['groupOp']]
    return fn(
                *(
                    [visit_expr(expr) for expr in rules['rules']] +
                    [visit_rule(subrule) for subrule in rules['groups']]
                )
            )

def visit_expr(expr):
    return lookup[expr["op"]](
                getattr(Thing, expr["field"]),
                expr["data"]
            )

# thing."Rate" = :Rate_1 AND (thing."Code" = :Code_1 OR thing."Name" = :Name_1)
print visit_rule(rules)