cod*_*ape 42 python sql parsing pyparsing
我想在非关系数据存储之上创建一个SQL接口.非关系数据存储,但以关系方式访问数据是有意义的.
我正在研究使用ANTLR生成一个AST,它将SQL表示为关系代数表达式.然后通过评估/遍历树来返回数据.
我之前从未实现过解析器,因此我想就如何最好地实现SQL解析器和求值程序提出一些建议.
更新:
我使用pyparsing实现了一个简单的SQL解析器.结合对我的数据存储实现关系操作的Python代码,这非常简单.
正如我在其中一条评论中所说,演习的重点是将数据提供给报告引擎.为此,我可能需要实现ODBC驱动程序.这可能是很多工作.
Dav*_*ick 37
我已经非常广泛地研究了这个问题.Python-sqlparse是一个非验证解析器,它实际上并不是你需要的.antlr中的示例需要大量工作才能在python中转换为优秀的ast.sql标准语法在这里,但是自己转换它们将是一个全职工作,很可能你只需要它们的一个子集,即没有连接.您也可以尝试查看gadfly(python sql数据库),但我避免使用他们自己的解析工具.
就我而言,我基本上只需要一个where子句.我尝试用pyparsing编写的booleneo(一个布尔表达式解析器)但最终从头开始使用pyparsing.Mark Rushakoff的reddit帖子中的第一个链接给出了一个使用它的sql示例.飞快移动全文搜索引擎也使用它,但我没有看过源,看看如何.
Pyparsing非常易于使用,您可以非常轻松地将其定制为与sql不完全相同(大多数语法不需要).我不喜欢ply,因为它使用命名约定使用了一些魔法.
总之尝试pyparsing,它很可能足够强大,可以满足您的需求,并且与python的简单集成(具有简单的回调和错误处理)将使体验变得非常轻松.
TwoLaid 的 Python SQL Parser 非常适合我的目的。它是用 C 编写的,需要编译。它很坚固。它解析出每个子句的各个元素。
https://github.com/TwoLaid/python-sqlparser
我正在使用它来解析要在报告标题中使用的查询列名称。这是一个例子。
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']
Run Code Online (Sandbox Code Playgroud)