使用 peewee 构建 FIQL 查询
Building a FIQL query with peewee
我正在尝试创建一个接受 FIQL formatted string and return a peewee 表达式的函数。
假设我有 url FIQL 格式的参数,如下所示:
fiql_str = "name==Foo,(country==USA;city==Kansas)"
使用 FIQL Parser 我可以取回这个对象:
['OR', ('name', '==', 'Foo'), ['AND', ('country', '==', 'USA'), ('city', '==', 'Kansas')]]
我想做的是创建一个接受上述对象的函数,并创建一个 peewee 可以理解的表达式。我习惯了 django & Q objects,在这里我可以像这样将表达式链接在一起:
fm = Q()
for mapping in mappings:
fm |= Q(subscription__approver=mapping.user)
return self.filter(fm)
我试过用 peewee 的 Query Builder / Node 模仿这个:
def map_to_filter(expressions, node):
expression = expressions.pop(0)
if type(expression) == str:
if expression == "OR":
node |= map_to_filter(expressions, node)
if expression == "AND":
node &= map_to_filter(expressions, node)
elif type(expression) == tuple:
return getattr(Store, expression[0]) + expression[1] + expression[2]
elif type(expression) == list:
map_to_filter(expression, node)
return node
result = map_to_filter(expressions, peewee.Node())
但我收到 NotImplementedError:
/lib/python3.7/site-packages/peewee.py in __sql__(self, ctx)
616
617 def __sql__(self, ctx):
--> 618 raise NotImplementedError
619
620 @staticmethod
NotImplementedError:
是否可以构建这样的功能?否则,还有哪些 tools/pluggins 可用于解决此问题?
您的问题来自使用裸 Node
,它不对应于任何 SQL(因此,没有 sql 方法) .
我建议累积一个列表并使用 functools.reduce()
将它们组合起来。
例如,
list_of_conds = [
(model.field1 == 'val1'),
(model.field2 == 'bar')]
reduce(operator.and_, list_of_conds)
如有必要,您可以将 reduce 函数切换为 operator.or_,然后继续使用深度优先搜索。
我正在尝试创建一个接受 FIQL formatted string and return a peewee 表达式的函数。
假设我有 url FIQL 格式的参数,如下所示:
fiql_str = "name==Foo,(country==USA;city==Kansas)"
使用 FIQL Parser 我可以取回这个对象:
['OR', ('name', '==', 'Foo'), ['AND', ('country', '==', 'USA'), ('city', '==', 'Kansas')]]
我想做的是创建一个接受上述对象的函数,并创建一个 peewee 可以理解的表达式。我习惯了 django & Q objects,在这里我可以像这样将表达式链接在一起:
fm = Q()
for mapping in mappings:
fm |= Q(subscription__approver=mapping.user)
return self.filter(fm)
我试过用 peewee 的 Query Builder / Node 模仿这个:
def map_to_filter(expressions, node):
expression = expressions.pop(0)
if type(expression) == str:
if expression == "OR":
node |= map_to_filter(expressions, node)
if expression == "AND":
node &= map_to_filter(expressions, node)
elif type(expression) == tuple:
return getattr(Store, expression[0]) + expression[1] + expression[2]
elif type(expression) == list:
map_to_filter(expression, node)
return node
result = map_to_filter(expressions, peewee.Node())
但我收到 NotImplementedError:
/lib/python3.7/site-packages/peewee.py in __sql__(self, ctx)
616
617 def __sql__(self, ctx):
--> 618 raise NotImplementedError
619
620 @staticmethod
NotImplementedError:
是否可以构建这样的功能?否则,还有哪些 tools/pluggins 可用于解决此问题?
您的问题来自使用裸 Node
,它不对应于任何 SQL(因此,没有 sql 方法) .
我建议累积一个列表并使用 functools.reduce()
将它们组合起来。
例如,
list_of_conds = [
(model.field1 == 'val1'),
(model.field2 == 'bar')]
reduce(operator.and_, list_of_conds)
如有必要,您可以将 reduce 函数切换为 operator.or_,然后继续使用深度优先搜索。