用PythonparsingSQL

我想在非关系数据存储上创build一个SQL接口。 非关系数据存储,但以关系方式访问数据是有意义的。

我正在研究使用ANTLR生成一个代表SQL作为关系代数expression式的AST。 然后通过评估/行走树来返回数据。

我从来没有实现过一个parsing器,因此我想就如何最好地实现SQLparsing器和评估器提供一些build议。

  • 上面描述的方法是否正确?
  • 还有其他的工具/库我应该看看? 像PLY或Pyparsing一样 。
  • 指向将帮助我的文章,书籍或源代码是赞赏。

更新:

我使用pyparsing实现了一个简单的SQLparsing器。 结合对我的数据存储实现关系操作的Python代码,这非常简单。

正如我在其中一个评论中所说的那样,这个练习的重点是使数据可用于报告引擎。 要做到这一点,我可能需要实现一个ODBC驱动程序。 这可能是很多工作。

我已经相当广泛地研究了这个问题。 Python-sqlparse是一个非validation的parsing器,它不是你真正需要的。 在antlr中的例子需要大量的工作来转换成一个很好的python。 SQL标准语法在这里 ,但它将是一个全职工作,自己进行转换,它可能是你只需要他们的一个子集,即没有联接。 你可以试着看看gadfly (一个python sql数据库),但是我避免了这个问题,因为他们使用了自己的parsing工具。

就我而言,我只需要一个where子句。 我尝试了用pyparsing编写的booleneo (一个布尔expression式分析器),但是最终从头开始使用pyparsing。 Mark Rushakoff的reddit文章中的第一个链接给出了一个使用它的sql示例。 飞马一个全文search引擎也使用它,但我没有看过源,看看如何。

Pyparsing非常易于使用,您可以很容易地将其定制为与sql(大部分不需要的语法)完全相同。 我不喜欢它,因为它使用了一些使用命名约定的魔法。

简而言之,pyparsing一个尝试,它将最有可能足够强大,做你所需要的,简单的与python(易于callback和error handling)整合将使经验相当轻松。

这reddit后build议Python-sqlparse作为一个现有的实现,在其他一些链接。

TwoLaid的Python SQL Parser对我的目的非常有效。 它是用C编写的,需要编译。 这是强大的。 它parsing每个子句的各个元素。

https://github.com/TwoLaid/python-sqlparser

我使用它来parsing查询列名称以在报告标题中使用。 这是一个例子。

 import sqlparser def get_query_columns(sql): '''Return a list of column headers from given sqls select clause''' columns = [] parser = sqlparser.Parser() # Parser does not like new lines sql2 = sql.replace('\n', ' ') # Check for syntax errors if parser.check_syntax(sql2) != 0: raise Exception('get_query_columns: SQL invalid.') stmt = parser.get_statement(0) root = stmt.get_root() qcolumns = root.__dict__['resultColumnList'] for qcolumn in qcolumns.list: if qcolumn.aliasClause: alias = qcolumn.aliasClause.get_text() columns.append(alias) else: name = qcolumn.get_text() name = name.split('.')[-1] # remove table alias columns.append(name) return columns sql = ''' SELECT aa, replace(coalesce(ab, 'x'), 'x', 'y') as jim, a.bla as sally -- some comment FROM table_a as a WHERE c > 20 ''' print get_query_columns(sql) # output: ['a', 'jim', 'sally'] 

当然,最好在Google Code上使用python-sqlparse

更新:现在我看到这个build议 – 我同意这是值得的: