Как я могу получить DELETE запросы из списка вакансий BigQuery? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть секционированная таблица времени приема, в которой нет строки для диапазона дат

#standardSQL
SELECT COUNT(*) AS rows_cnt,
       _PARTITIONTIME AS ptime
FROM my_dataset.my_table
WHERE _PARTITIONTIME BETWEEN '2017-01-01' AND '2017-01-30'
GROUP BY ptime
-- result returned zero rows :o

Я хочу исследовать: вероятно, что данные в этих разделах были стерты с помощью какого-либо запроса на удаление,Я написал скрипт для извлечения «подозрительных» запросов. У них есть какой-то шаблон

DELETE ...my_table .... 2017-01 ...

или просто УДАЛИТЬ задания

, вот скрипт

import re
import requests
import json
from pprint import pprint
from datetime import datetime
import subprocess
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-all_users', type=bool, default=True)
parser.add_argument('-projection', type=str, default='full')
parser.add_argument('-state_filter', type=str, default='done')
parser.add_argument('-access_token', type=str)
args = parser.parse_args()


def get_query_string(job):
    return job['configuration']['query']['query']

def log_job(job):
    with open('suspicious_jobs.txt', 'a+') as f:
        f.writelines(json.dumps(job))
        f.writelines('\n')

def is_suspicious_query(query_string):
    lower_query = query_string.lower()
    return re.search('delete.*my_table.*2017-01', lower_query) is not None

def is_delete_statement(job):
    return job['statistics']['query']['statementType'] == 'DELETE'

def is_copy_job(job):
    return job['configuration']['jobType'] == 'COPY'

def get_next_token():
    subprocess.check_call('gcloud auth login', shell=True)
    return subprocess.check_output('gcloud auth print-access-token', shell=True).decode('utf-8').strip()


all_users = args.all_users
projection = args.projection
state_filter = args.state_filter
query_url = """https://www.googleapis.com/bigquery/v2/projects/my_project_id/jobs"""
access_token = get_next_token()

next_page_token = ''
page = 1
while next_page_token is not None:
    print('######## querying page ', page)
    url_parameters = {
    'allUsers': all_users,
    'pageToken': next_page_token,
    'projection': projection,
    'stateFilter': state_filter
    }
    headers = {
    'Authorization': 'Bearer {}'.format(access_token)
    }
    r = requests.get(query_url, params=url_parameters, headers=headers)

    if r.status_code == 401:
        access_token = get_next_token()
        print(access_token)
        print(r.text)
        continue
    elif r.status_code != 200:
        print(r.text)
        print('###### last_page_token is ', next_page_token)
        break

    next_page_token = r.json().get('nextPageToken', None)
    jobs = r.json().get('jobs', [])
    for j in jobs:
        try:
            if is_copy_job(j):
                continue
            q = get_query_string(j)
            if is_suspicious_query(q) or is_delete_statement(j):
                log_job(j)

        except KeyError as e:
            pass

    page = page + 1

is_suspicious_query Функция проверяет, соответствует ли запрос шаблону delete.*my_table.*2017-01 (без учета регистра).

Я не смог найти работу, которая выполняла удаление.Я пропускаю работу в моем цикле пока?(Я пропускаю всякий раз, когда у меня возникает исключение KeyError)

Можно ли удалить разделы таблицы без регистрации действия?

1 Ответ

0 голосов
/ 28 февраля 2019

Для этого я предлагаю использовать Расширенные фильтры Stackdriver со следующим фильтром:

resource.type="bigquery_resource"
protoPayload.serviceData.jobQueryRequest.query:"your_dataset.your_table"
protoPayload.serviceData.jobQueryResponse.job.jobConfiguration.query.statementType="DELETE"

При этом вы получите операции DELETE, выполненные для указанной таблицы.

ОБНОВЛЕНИЕ:

resource.type="bigquery_resource"
(protoPayload.methodName="jobservice.jobcompleted"
OR protoPayload.authorizationInfo.resource:"projects/<your-project>/datasets/<your-dataset>/tables/"
OR (protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.destinationTable.datasetId="<your-dataset>"
AND protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.destinationTable.tableId:"<your-table>"))
protoPayload.methodName!="tabledataservice.list"
"<yourdataset.yourtable>"
severity!="ERROR"

С помощью этого фильтра вы можете найти большинство операций над таблицей, например, запрос с WriteDisposition с WRITE_TRUNCATE в качестве значения, обрежет вашу таблицу и напишет ее с самого начала.Обратите внимание, что если вы используете : вместо = при использовании ваших фильтров, он работает для поиска частичных строк.

Относительно вопросов вашего раздела, насколько я знаю, когда раздел удаляется, он долженбыть перечислены как УДАЛЕНО в журналах.Более того, вы удаляете разделы с помощью инструмента командной строки bq rm вместе с декоратором таблиц .

Надеюсь, это вам поможет.

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