相关文章推荐
绅士的茴香  ·  安装cplex到python_mob64ca ...·  2 周前    · 
严肃的松树  ·  Ubuntu下Python3解决module ...·  1 周前    · 
捣蛋的手套  ·  ABAP内表(internal ...·  1 月前    · 
道上混的消炎药  ·  Android ...·  1 年前    · 
挂过科的海龟  ·  Keep the Screen from ...·  1 年前    · 

用Python解析SQL

58 人关注

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

我正在考虑使用 ANTLR 来产生一个AST,将SQL表示为关系代数表达式。然后通过评估/行走树来返回数据。

我以前从来没有实现过分析器,因此我想得到一些建议,如何最好地实现一个SQL分析器和评估器。

  • Does the approach described above sound about right?
  • Are there other tools/libraries I should look into? Like PLY or Pyparsing .
  • Pointers to articles, books or source code that will help me is appreciated.
  • 我使用pyparsing实现了一个简单的SQL解析器。结合Python代码来实现对我的数据存储的关系操作,这相当简单。

    正如我在一个评论中所说,这项工作的重点是使数据对报告引擎可用。要做到这一点,我可能需要实现一个ODBC驱动。这可能是一个很大的工作。

    3 个评论
    为什么对对象施加SQL限制? 有什么好处? OQL有什么问题? en.wikipedia.org/wiki/Object_Query_Language
    将要获得的。一个大量的报告工具可以使用的查询界面。我计划在客户端实现一个ODBC驱动。这样,商业用户就可以使用Crystal Reports、Excel等从数据存储中获取数据了。OQL,虽然可能是一种很好的查询语言(我从来没有用过),但它不像SQL那样广泛传播。
    van
    +1 都是:OO数据库的最大问题之一正是缺乏报告引擎 :(
    python
    sql
    parsing
    pyparsing
    codeape
    codeape
    发布于 2009-09-09
    5 个回答
    David Raznick
    David Raznick
    发布于 2021-06-09
    已采纳
    0 人赞同

    我已经相当广泛地研究了这个问题。Python-sqlparse是一个非验证解析器,这并不是你真正需要的。 antlr中的例子需要大量的工作来转换为python中的一个漂亮的 ast。 sql的标准语法是 here 但是,自己转换这些数据是一项全职工作,而且你可能只需要其中的一个子集,即没有连接。你可以试着看一下 牛虻 (一个Python SQL数据库)也是如此,但我避开了它,因为他们使用自己的解析工具。

    对于我的情况,我基本上只需要一个where子句。我试着 booleneo (一个布尔表达式分析器)写的,但最后还是从头使用了pyparsing。 Mark Rushakoff的reddit帖子中的第一个链接给出了一个使用它的SQL例子。 Whoosh 一个全文搜索引擎也使用它,但我还没有看清源头,不知道如何使用。

    Pyparsing非常容易使用,你可以非常容易地定制它,使之不与SQL完全相同(大部分语法你将不需要)。我不喜欢ply,因为它使用了一些使用命名惯例的魔法。

    总之,给pyparsing一个尝试,它很可能强大到足以完成你所需要的,而且与python的简单集成(带有简单的回调和错误处理)将使你的体验相当轻松。

    谢谢你的经验分享。从最初对python-sqlparse非常有限的测试来看,我似乎可以使用它。我将尝试在python-sqlparse中使用 parse 函数的返回值。但无论如何,我都会研究一下pyparsing。
    Pyparsing是一个很好的工具,周围有很多解析sql的例子。
    这个海报在pyparsing wiki ( pyparsing.wikispaces.com/message/view/home/14105203 )刚刚报告完成了一个SQL SELECT解析器--也许你可以联系他/她寻求帮助、建议,甚至是代码。
    淘宝网。我已经联系了发帖人。
    我使用pyparsing实现了它。Pyparsing在这方面工作得很好。
    Mark Rushakoff
    Mark Rushakoff
    发布于 2021-06-09
    0 人赞同

    This reddit post suggests python-sqlparse 作为一个现有的实现,以及其他一些链接。

    谢谢你的建议。Python-sqlparse看起来很有趣,我将会试一试。
    这篇文章已经有一段时间没有发布了--现在有了 github.com/macbre/sql-metadata 它是建立在上述 sqlparse 库上的。替换代码1】不会给你一个AST,但会从查询中提取已解决的列和表名。
    dlink
    dlink
    发布于 2021-06-09
    0 人赞同

    TwoLaid的Python SQL解析器对于我的目的来说非常好用。 它是用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 
       replace(coalesce(a.b, 'x'), 'x', 'y') as jim,
       a.bla as sally  -- some comment
       table_a as a
    WHERE
    print get_query_columns(sql)
    # output: ['a', 'jim', 'sally']
        
    Python SQL解析器不支持Python 3
    Barton
    Barton
    发布于 2021-06-09
    0 人赞同

    当然,最好的办法可能是利用 谷歌代码上的python-sqlparse

    更新:现在我看到有人建议这样做--我同意这样做是值得的。

    Overbryd
    Overbryd
    发布于 2021-06-09
    0 人赞同

    我正在使用 python-sqlparse ,取得了巨大的成功。