10

我正在开发一个项目(用 Django 编写),它只有几个实体,但每个实体有很多行。

在我的应用程序中,我有几个静态“报告”,直接用普通 SQL 编写。用户还可以通过通用过滤器表单搜索数据库。由于目标受众非常精通技术,并且在某些时候过滤器无法满足他们的需求,我考虑为我的数据库创建一种查询语言,例如YQLJira 的高级搜索

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

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

4

4 回答 4

14

使用PLY编写这样的 DSL 实际上非常容易,而且,在 Django 中,已经有一个示例可用于执行您想要的操作。你看,Django 有一个叫做Q对象的奇特的东西,它使 Django 查询事情变得相当容易。

在 2012 年 DjangoCon EU 上,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,然后在构造对象之前.替换为)。__Qp_expression_ID

所以,这就满足了简单的查询;如果您希望制作更复杂的 DSL,它还为您提供了一个很好的起点。

于 2013-02-08T20:20:12.500 回答
3

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

然而,高级用户要求更多。我决定已经有一个他们都知道的DSL - SQL。问题是如何使它足够安全。

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

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

TL;DR - SQL 是要走的路!

于 2012-06-09T09:33:43.340 回答
1

实际上,您可以使用pyparsing编写自己的 SQL 语言。您甚至可以扩展非常详细的示例。

于 2013-02-08T20:06:50.920 回答
1

根据数据的形式、用户需要使用的查询类型以及数据更新的频率,Nick Craig-Wood 建议的纯 SQL 解决方案的替代方案是在Solr中索引您的数据,然后运行对它的查询。

Solr 增加了一层复杂性(配置、数据同步),但速度超快,可以处理大型数据集,并提供(相对)直观的查询语言。

于 2012-06-09T09:55:21.673 回答