如何使用sqlfluff生成SQL?

问题描述 投票:0回答:1

我有以下示例 SQL(它变得更复杂):

select
    *
from
    (select
        a,
        b
    from
        agents)

我想使用sqlfluff解析这样的字符串

from sqlfluff.core import Parser
p = Parser(dialect='ansi')
parsed = p.parse_string(query)

并将查询分成两部分(最好分成两棵树/ParsedString),外部的和内部的。内部查询应插入到 CTAS 语句中,外部查询应引用它。

预期的伪代码:

outer_tree.set_innermost_token('reagents')
inner_tree.set_outermost_tokens('create or replace reagents as')
print(outer_tree.generate_SQL())
# !!! for simplicity I am removing the indentation
# select * from reagents
print(inner_tree.generate_SQL())
# !!! for simplicity I am removing the indentation
# create or replace reagents as select a, b from agents

请记住,这只是一个简单的示例,我知道基本的正则表达式在这种情况下可以有所帮助,但是,我的目标是修改更复杂的查询。另外,SQL 查询已经写好了,因此我不能只写一个生成器。

谢谢指点!

我查看了 cli.py 以及 Linter 的内部结构,但我只能生成与提供的相同的 SQL 代码(通过将第 222 行上的变量

filtered_source_patches
设置为
None
) .

python sqlfluff
1个回答
0
投票
您是正确的,您可以使用

Parser

 类获取解析的结构,但您可能会发现 
parse_string()
 类上的 
Linter
 方法更有用。获得解析后的对象后,您可以使用 
recursive_crawl
 来查找特定类型的段。在下面的示例中,我们搜索 
select_statement
 段,您可以看到我们找到了两个(一个嵌套在另一个内)。

from sqlfluff.core import Linter # Whitespace removed for brevity input_sql = "select * from (select a, b from agents)" parsed = Linter(dialect="ansi").parse_string(input_sql) print("File:", parsed.tree.raw) # File: select * from (select a, b from agents) for idx, outer_select in enumerate(parsed.tree.recursive_crawl("select_statement")): print("Inner:", idx, outer_select.raw) # Inner: 0 select * from (select a, b from agents) # Inner: 1 select a, b from agents
听起来您想从内部生成一个 

CREATE TABLE

 语句,您可以通过简单的字符串操作来完成。替换外部 SQL 中的内容有点困难,但是您可以利用上面 
pos_marker
 变量的 
outer_segment
 属性中存储的位置信息来找出外部文件中的 
where 进行一些字符串操作.

© www.soinside.com 2019 - 2024. All rights reserved.