Вы можете использовать функцию из скрипта , доступного в примерах python -sqlparse для извлечения данных:
def extract_definitions(token_list):
# assumes that token_list is a parenthesis
definitions = []
tmp = []
par_level = 0
for token in token_list.flatten():
if token.is_whitespace:
continue
elif token.match(sqlparse.tokens.Punctuation, '('):
par_level += 1
continue
if token.match(sqlparse.tokens.Punctuation, ')'):
if par_level == 0:
break
else:
par_level += 1
elif token.match(sqlparse.tokens.Punctuation, ','):
if tmp:
definitions.append(tmp)
tmp = []
else:
tmp.append(token)
if tmp:
definitions.append(tmp)
return definitions
и использовать for-l oop для печати информации об именах столбцов и их типах данных:
parsed = sqlparse.parse(line)[0]
# extract the parenthesis which holds column definitions
_, par = parsed.token_next_by(i=sqlparse.sql.Parenthesis)
columns = extract_definitions(par)
for column in columns:
print(f"column: {column[0]}")
print(f"data type: {' '.join(str(t) for t in column[1:])}")
Этот код дает следующий результат:
column: actor_id
data type: integer DEFAULT nextval 'public.actor_actor_id_seq' :: regclass NOT NULL
column: first_name
data type: character varying 45 NOT NULL
column: last_name
data type: character varying 45 NOT NULL
column: last_update
data type: timestamp without time zone DEFAULT now NOT NULL
На самом деле это немного больше информации, чем вы хотели. Тем не менее, эти строки должны быть легко "regexable" для извлечения только базовых c типов данных.
Как уже упоминалось в комментариях, использование специальной информации (например, DISTSTYLE
) заставляет синтаксический анализатор не распознавать sqlparse.sql.Parenthesis
и была отмечена как ошибка . Таким образом, такую информацию необходимо удалить из запроса SQL перед синтаксическим анализом.