用Python解析SQL
我想在非关系数据存储上创建一个SQL接口。非关系数据存储,但以关系方式访问数据是有意义的 我正在研究如何使用生成一个将SQL表示为关系代数表达式的AST。然后通过计算/遍历树返回数据 我以前从未实现过解析器,因此,我想了解一些关于如何最好地实现SQL解析器和计算器的建议用Python解析SQL,python,sql,parsing,pyparsing,Python,Sql,Parsing,Pyparsing,我想在非关系数据存储上创建一个SQL接口。非关系数据存储,但以关系方式访问数据是有意义的 我正在研究如何使用生成一个将SQL表示为关系代数表达式的AST。然后通过计算/遍历树返回数据 我以前从未实现过解析器,因此,我想了解一些关于如何最好地实现SQL解析器和计算器的建议 上述方法听起来正确吗 是否还有其他工具/库需要我研究?喜欢还是喜欢 如果您能给我一些文章、书籍或源代码方面的建议,我将不胜感激 更新: 我使用pyparsing实现了一个简单的SQL解析器。结合对我的数据存储实现关系操作的P
- 上述方法听起来正确吗
- 是否还有其他工具/库需要我研究?喜欢还是喜欢
- 如果您能给我一些文章、书籍或源代码方面的建议,我将不胜感激
正如我在其中一条评论中所说的,这项工作的目的是让数据可供报告引擎使用。为此,我可能需要实现一个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代码可以对结构做出一些合理的假设
parse
函数返回的值。但我将研究pyparsinPyparsing是一个很好的工具,有很多解析sql的例子刚刚报告完成了一个SQL SELECT解析器-也许您可以联系他/她寻求帮助、建议,甚至code.TFTT。我已经联系了海报。我使用pyparsing实现了它。pyparsing在这方面非常有效。Python SQL解析器不支持Python 3