【发布时间】:2018-01-28 21:28:47
【问题描述】:
我正在寻找一种方法将我工作场所的过滤功能公开给其他开发人员和可选的客户。
问题
我想基于用户定义的过滤器对我的数据(python dicts)实现一种简单的查询语言,这些过滤器向我的其他开发人员以及后来向我们的客户公开。
- 语言应该足够简单,以供非开发人员使用
- 足够安全,可以避免在我的服务器上执行远程代码
- 足够表达,可以像下面的例子那样查询数据
在我的 dict / json 数据上公开 SQL 接口会很棒(我不喜欢设置服务器)
示例场景
db = [
{'first': 'john', 'last': 'doe', 'likes': ['cookies', 'http']},
{'first': 'jane', 'last': 'doe', 'likes': ['cookies', 'donuts']},
{'first': 'danny', 'last': 'foo', 'likes': ['http', 'donuts']},
]
query = '(first == "john" or last == "doe") and likes contains "cookies"'
results = run_query(db, query)
这应该返回(在结果中):
[
{'first': 'john', 'last': 'doe', 'likes': ['cookies', 'http']},
{'first': 'jane', 'last': 'doe', 'likes': ['cookies', 'donuts']},
]
注意:我不介意更改运营商名称,例如or -> OR contains -> inside 或其他任何东西,只要它是人类可读的并且保持语言的相同表达性
我尝试过的解决方案
DSL
我查看了一些 DSL 库,例如 PLY,但在我看来它们太复杂了,并且需要一些魔法才能完成任务(不确定从哪里开始以及是否值得)
插件
没有找到任何插件系统为我的用户公开沙盒功能(即更安全的评估)
JSON 查询包
我查看了TinyDB 和其他通过 json 实现某种 SQL 的方法,但如果没有大量自定义,我找不到可以工作的东西。 我还查看了pandasql,它总体上看起来不错,但没有维护库:(
有一个 lucene 包解析器 - luqum 基于 PLY 但它与我的语法树不同(它们有更多方法)并且 lib 没有真正维护,(我确实考虑稍微操纵这个 lib 以获得我想要什么)
SQLite
使用 SQLiteDB 加载我的所有数据(无论是否在内存中),然后对其运行 SQL 查询。没有测试它,但这应该很简单,将我的整个数据加载到 SQL 中只是为了运行我不想做的数据。
我愿意接受建议,甚至对如何改进上述解决方案以使其发挥作用
【问题讨论】:
-
可能使用
pandas已经可以为您提供很多功能,尤其是DataFrame.query(..)部分。 -
感谢@WillemVanOnsem,但我可以将查询字符串传递给它吗?如果没有,我应该在传递给
df.query(..)之前解析查询字符串你知道怎么做吗? -
是的,但它不适用于会员检查(
contains等)
标签: python json python-3.x abstract-syntax-tree