Извлечь исходные и целевые таблицы из Sql файла, используя Python или любой язык - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь извлечь исходную и целевую таблицы из файла sql, используя python. До сих пор я могу извлекать их, используя простой код python, который ищет ключевые слова «from, join, insert, create» для извлечения имен таблиц. Но теперь я делаю это для процедур, которые могут содержать функции и могут использоваться после может войти в мой список источников, чего я не хочу. Я пытался удалить его, но не смог. Я вставляю свой код, из которого я извлекал свой источник и цель

def tables_in_query(sql_str):
    # remove the /* */ comments
    q = re.sub(r'/\*[^*]*\*+(?:[^*/][^*]*\*+)*/', "", sql_str)

    # remove whole line -- and # comments
    lines = [line for line in q.splitlines() if not re.match("^\\s*(--|#)", line)]

    # remove trailing -- and # comments
    q = " ".join([re.split("--|#", line)[0] for line in lines])

    # split on blanks, parenthesis and semicolons
    tokens = re.split(r"[\s)(;]+", q)

    source, target, target_views, with_1 = set(), set(), set(), set()


    view_idx = [i+1 for i, x in enumerate(tokens) if x.lower() in ["view"]]
    for i in view_idx:
        target_views.add(tokens[i])

    with_index = [i + 1 for i, x in enumerate(tokens) if x.lower() in ["with"]]
    for i in with_index:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() in ["table", "replace"]):
            with_1.add(t)

    target_index = [i + 3 for i, x in enumerate(tokens) if x.lower() in ["create"]]
    for i in target_index:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() in ["table", "replace"]) and not with_1.__contains__(
                t.lower()):
            target.add(t)

    target_index = [i + 2 for i, x in enumerate(tokens) if x.lower() in ["insert"] and tokens[i+1].lower() in ["into"]]
    for i in target_index:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() in ["table", "replace"]) and not with_1.__contains__(
                t.lower()):
            target.add(t)


    target_idx = [i + 1 for i, x in enumerate(tokens) if x.lower() in ["update"]]
    for i in target_idx:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() in ["table", "replace"]) and not with_1.__contains__(
                t.lower()):
            target.add(t.replace('..', '.admin.'))

    source_index = [i + 1 for i, x in enumerate(tokens) if x.lower() in ["from", "join"]]
    for i in source_index:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() == "select" or t.lower() == "" or t.lower().startswith("substr") or t.lower().startswith("last_day")) and not with_1.__contains__(
                t.lower()):
            source.add(t)
            # print(t)

    source_idx = [i + 2 for i, x in enumerate(tokens) if x.lower() in ["alter"]]
    for i in source_idx:
        t = tokens[i]
        if not (t.lower().startswith('tmp') or t.lower() == "select" or t.lower() == "") and not with_1.__contains__(
                t.lower()):
            source.add(t)

    return source, target, target_views

1 Ответ

0 голосов
/ 17 июня 2020

Мне кажется, много работы. Я предлагаю вам использовать проверенные и проверенные решения, такие как sql -метаданные (https://github.com/macbre/sql-metadata) amd sql -parse (https://github.com/andialbrecht/sqlparse)

В качестве альтернативы, если вы используете SQLITE - и, возможно, другие механизмы базы данных - вы также можете попробовать использовать EXPLAIN, чтобы получить таблицу байт-кодов для интересующего вас оператора SQL, а затем поищите коды операций таблицы, такие как OpenRead (исходная таблица), OpenWrite (целевая таблица) и DropTable (целевая таблица?). Ссылки на таблицы находятся в столбце P2, в котором вы можете найти таблицу SQLITE_MASTER, чтобы получить имена таблиц. Это имеет то преимущество, что, если ваш оператор SQL ссылается на представление, байт-код вместо этого будет ссылаться на базовые таблицы, что не покажет никакой объем синтаксического анализа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...