Вы не можете использовать регулярное выражение здесь, потому что синтаксис SQL не формирует регулярные шаблоны, которые вы могли бы сопоставить с механизмом Python re
.Вам действительно нужно разобрать строку в поток токенов или синтаксическое дерево;Ваш SUM(...)
может содержать широкий массив синтаксиса, включая подвыборы, в конце концов.
Библиотека sqlparse
может сделать это, даже если это бит недокументированный и не очень дружественный для внешнего использования .
Повторное использование функции walk_tokens
, которую я определил в другом посте, на который я ссылался:
from collections import deque
from sqlparse.sql import TokenList
def walk_tokens(token):
queue = deque([token])
while queue:
token = queue.popleft()
if isinstance(token, TokenList):
queue.extend(token)
yield token
извлечение последнего элемента изтогда список идентификаторов SELECT
выглядит следующим образом:
import sqlparse
from sqlparse.sql import IdentifierList
tokens = sqlparse.parse(sql)[0]
for tok in walk_tokens(tokens):
if isinstance(tok, IdentifierList):
# iterate to leave the last assigned to `identifier`
for identifier in tok.get_identifiers():
pass
break
print(identifier)
Демонстрация:
>>> sql = '''\
... SUM(case when(A.money-B.money>1000
... and A.unixtime-B.unixtime<=890769
... and B.col10 = "A"
... and B.col11 = "12"
... and B.col12 = "V") then 10
... end) as finalCond0,
... MAX(case when(A.money-B.money<0
... and A.unixtime-B.unixtime<=6786000
... and B.cond1 = "A"
... and B.cond2 = "4321"
... and B.cond3 in ("E", "F", "G")) then A.col10
... end) as finalCond1,
... SUM(case when(A.money-B.money>0
... and A.unixtime-B.unixtime<=6786000
... and B.cond1 = "A"
... and B.cond2 = "1234"
... and B.cond3 in ("A", "B", "C")) then 2
... end) as finalCond2
... '''
>>> tokens = sqlparse.parse(sql)[0]
>>> for tok in walk_tokens(tokens):
... if isinstance(tok, IdentifierList):
... # iterate to leave the last assigned to `identifier`
... for identifier in tok.get_identifiers():
... pass
... break
...
>>> print(identifier)
SUM(case when(A.money-B.money>0
and A.unixtime-B.unixtime<=6786000
and B.cond1 = "A"
and B.cond2 = "1234"
and B.cond3 in ("A", "B", "C")) then 2
end) as finalCond2
identifier
является экземпляром sqlparse.sql.Identifier
, но снова преобразуется в строку (что * 1027)* делает, или вы можете просто использовать str()
) снова выдает входную строку SQL для этого раздела.