Клуб Яндекс.Метрики

Не получается выгрузить данные из Yandex Metrika Logs API в Clickhouse

westashop
20 ноября 2017, 10:51

Обидно, когда не получается вместе использовать два таких достойных продукта

Суть проблемы:
При выгрузке данных из Metrica Logs API, генерируются TSV файлы которые потом не распознаются парсером Clickhouse для TabSeparatedWithNames формата
и соответвенно не могут напрямую быть загружены  в локальный Clickhouse

вот основные ошибки
— одинарные ковычки, которые обрамляют строки в комплексных типах Array (String)
эскейпятся через \
пример это поля ym:s:goalsDateTime и  ym:s:goalsOrder

чтобы обойти это в «официальном загрузчике» стоит вот такой костыль
https://github.com/yndx-metrika/logs_api_integration/blob/master/logs_api.py#L170 
это делает загрузчик дико неэффективным по памяти (надо взять все данные и пройтись по ним заменой строк) и не позволяет грузить через него действительно большие объемы данных

— комплексные поля типа ym:s:goalsCurrency  — тип в Clickhouse Array (String), наоборот записываются без квотирования даже в одинарные ковычки, в результате вместо ['',''] получается [,]… 

— самое фиговое случается для поля ym:s:params сначала в нем добавляется экранирование через \, а потом, поскольку в значении поля встречаются двойные кавычки, добавляется их экранирование через задваивание, на выходе вместо Array (String) получается вот такая ерунда
 

"[\'{""__ym"":{""ads"":{""w"":{""t"":0,""l"":0,""w"":1366,""h"":656},""p"":""w"":1349,""h"":3965},""a""[],""full"":1}}}\']"


Что делать? Разработчики помогите пофиксить баги и сделать продукт лучше?

2 комментария
Добрый день!


Напишите в Службу поддержки API Метрики: https://tech.yandex.ru/metrika/doc/troubleshooting/index-docpage/ 
a.i.miraev@tmn2.etagi.com
23 ноября, 22:28
Василий,
доброго времени суток. Я тоже столкнулся с этим и накидал немного кода для обработки ym:s:params
Подскажите, есть ли у вас какое-то более-менее адекватное решение для этой задачи?

Свой код приведу тут, может кому-то понадобится:

import ast, re

str = "['{""test1"":""123""},{...},{...}']"

str0 = re.sub('"\[', r"[", str)

str1 = re.sub('\]"', r"]", str0)
str2 = re.sub('""', '"', str1)
str3 = re.sub(r'\'', '', str2)
result_list = ast.literal_eval(str3)
Обновлено 23 ноября, 22:29