用Python解析SQL

用Python解析SQL,python,sql,parsing,pyparsing,Python,Sql,Parsing,Pyparsing,我想在非关系数据存储上创建一个SQL接口。非关系数据存储,但以关系方式访问数据是有意义的 我正在研究如何使用生成一个将SQL表示为关系代数表达式的AST。然后通过计算/遍历树返回数据 我以前从未实现过解析器,因此,我想了解一些关于如何最好地实现SQL解析器和计算器的建议 上述方法听起来正确吗 是否还有其他工具/库需要我研究?喜欢还是喜欢 如果您能给我一些文章、书籍或源代码方面的建议,我将不胜感激 更新: 我使用pyparsing实现了一个简单的SQL解析器。结合对我的数据存储实现关系操作的P

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

我正在研究如何使用生成一个将SQL表示为关系代数表达式的AST。然后通过计算/遍历树返回数据

我以前从未实现过解析器,因此,我想了解一些关于如何最好地实现SQL解析器和计算器的建议

  • 上述方法听起来正确吗
  • 是否还有其他工具/库需要我研究?喜欢还是喜欢
  • 如果您能给我一些文章、书籍或源代码方面的建议,我将不胜感激
更新:

我使用pyparsing实现了一个简单的SQL解析器。结合对我的数据存储实现关系操作的Python代码,这相当简单


正如我在其中一条评论中所说的,这项工作的目的是让数据可供报告引擎使用。为此,我可能需要实现一个ODBC驱动程序。这可能需要做大量的工作。

建议将其作为一个现有的实现,以及一些其他链接。

我已经非常广泛地研究了这个问题。pythonsqlparse是一个非验证性解析器,这并不是您真正需要的。antlr中的示例需要大量工作才能转换为python中的漂亮ast。sql标准语法是,但是自己转换它们将是一项全职工作,而且很可能只需要它们的一个子集,即不需要连接。您也可以尝试查看(python sql数据库),但我避免了,因为他们使用自己的解析工具

就我而言,我只需要一个where子句。我尝试过用pyparsing编写(一个布尔表达式解析器),但最终从头开始使用pyparsing。MarkRushakoff的reddit文章中的第一个链接给出了一个使用它的sql示例。全文搜索引擎也使用它,但我还没有查看源代码以了解如何使用它

Pyparsing非常易于使用,您可以非常轻松地对其进行自定义,使其与sql不完全相同(大多数语法您都不需要)。我不喜欢ply,因为它使用了一些使用命名约定的魔法


简而言之,尝试一下pyparsing,它很可能强大到足以完成您需要的任务,并且与python的简单集成(具有简单的回调和错误处理)将使体验非常轻松

当然,最好是利用


更新:现在我看到有人建议了这一点——我同意这是值得的:

Twolay的Python SQL解析器在我看来运行得非常好。它是用C写的,需要编译。它是健壮的。它解析出每个子句的各个元素

我用它来解析出要在报告头中使用的查询列名。这里有一个例子

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 
   a.a,
   replace(coalesce(a.b, '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']

我正在使用
pythonsqlparse
并取得了巨大成功

在我的例子中,我正在处理已经验证过的查询,我的AST代码可以对结构做出一些合理的假设


为什么要对对象施加SQL限制?能得到什么?OQL有什么问题?获得:一个查询界面,大量的报告工具都可以使用。我计划在客户机上实现一个ODBC驱动程序。因此,业务用户可以使用Crystal Reports、Excel等从数据存储中获取数据。OQL虽然可能是一种很好的查询语言(我从未使用过),但不如SQL广泛传播。+1两者:OO数据库的最大问题之一就是缺少报告引擎:(感谢您的建议。Python sqlparse看起来很有趣,我将尝试一下。感谢您分享您的经验。从Python sqlparse的最初、非常有限的测试来看,我似乎可以使用它。我将尝试使用Python sqlparse中的
parse
函数返回的值。但我将研究pyparsinPyparsing是一个很好的工具,有很多解析sql的例子刚刚报告完成了一个SQL SELECT解析器-也许您可以联系他/她寻求帮助、建议,甚至code.TFTT。我已经联系了海报。我使用pyparsing实现了它。pyparsing在这方面非常有效。Python SQL解析器不支持Python 3