构建DSL查询语言

erc*_*cpe 9 python django dsl

我正在研究一个项目(用Django编写),它只有几个实体,但每个实体都有很多行.

在我的应用程序中,我有几个静态"报告",直接用纯SQL编写.用户还可以通过通用过滤器表单搜索数据库.由于目标受众真的精通技术,并且在某些时候过滤器不符合他们的需求,我想为我的数据库创建查询语言,如YQLJira的高级搜索.

我找到了http://sourceforge.net/projects/littletable/http://www.quicksort.co.uk/DeeDoc.html,但似乎它们只对内存中的对象进行操作.由于数据库可能太大而无法将其保存在内存中,我宁愿在执行实际工作之前将查询转换为SQL(或更好的Django查询).

有没有关于如何做到这一点的图书馆或最佳实践?

Chr*_*gan 14

使用PLY编写这样的DSL实际上非常简单,而且在Django中已经有了一个可以满足您的需求的例子.你看,Django有这个奇特的东西,叫做一个Q对象,让Django查询事情相当容易.

在DjangoCon EU 2012上,Matthieu Amiguet举办了一个题为在Django应用程序实现特定领域语言的会议,他在这个会议中完成了这个过程,直到根据需要实现这样的DSL.他的幻灯片包括你需要的所有内容,可以在他的网站上找到.无论如何,最终代码(最后一张幻灯片链接)可在http://www.matthieuamiguet.ch/media/misc/djangocon2012/resources/compiler.html上找到.

Reinout van Rees也对该会议发表了一些好评.(他通常会这样做!)这些内容涵盖了一些缺失的背景.

在给出的示例中,您会看到与YQL和JQL非常相似的内容:

  • groups__name="XXX" AND NOT groups__name="YYY"
  • (modified > 1/4/2011 OR NOT state__name="OK") AND groups__name="XXX"

它也可以很容易地调整; 例如,您可能想要使用groups.name而不是groups__name(我愿意).这种修饰可以由相当平凡(允许.在FIELD令牌,通过修改t_FIELD,然后更换.__构造之前Q在对象p_expression_ID).

因此,这满足简单的查询; 如果您希望制作更复杂的DSL,它还为您提供了一个良好的起点.


Nic*_*ood 3

我曾经遇到过这个问题 - 需要搜索的大型数据库。我使用django制作了一些静态报告和几个精美的过滤器(使用 django 非常简单),就像您一样。

然而,高级用户却要求更多。我认为已经有一种他们都知道的DSL —— SQL。问题是如何使其足够安全。

因此,我使用 django 权限来授予高级用户在新表中进行 SQL 查询的权限。然后,我为不太强大的用户提供了使用这些查询的视图。我让它们采用可选参数。这些查询是使用 Python 的较低级别的DB-API运行的,而 django 无论如何都在其 ORM 的底层使用该 API。

真正的技巧是打开只读数据库连接来运行这些查询,以确保没有运行任何更新。我通过在数据库中创建具有较低权限的不同用户并在视图中为其打开特定连接来建立只读连接。

TL;DR - SQL 是最佳选择!