Форматы
В разделе описаны типы данных и форматы представления табличных данных, поддерживаемые системой YTsaurus.
Типы данных
В системе YTsaurus хранятся данные следующих типов:
Разные форматы позволяют работать с разными типами данных.
Структурированные данные
Структурированные данные — дерево узлов с атрибутами, в котором узлы соответствуют YSON-типам (map, list, простые типы) с атрибутами.
Структурированные данные можно получить при помощи команды get
.
Поддерживаемые форматы: json
, yson
.
Пример: узлы Кипариса, их атрибуты.
Табличные данные
Табличные данные — последовательность строк, в которой каждая строка логически представляет собой пару ключ-значение, где ключ — строка, значение — структурированные данные.
Поддерживаемые форматы: json
, yson
, dsv
, schemaful_dsv
, protobuf
, arrow
.
Примеры: входные и выходные данные операций, входные данные команды write_table
, выходные данные команды read_table
.
Бинарные данные
Бинарные данные — последовательность байтов. Например, в файлах хранятся бинарные данные.
Поддерживаемые форматы: задать формат нельзя. Представление только в виде массива байтов.
Примеры: входные данные команды upload
и выходные данные команды download
.
Форматы представления табличных данных
В YTsaurus поддерживается несколько форматов данных, которые определяют, в каком виде данные будут переданы системе или получены от нее.
Для всех команд утилиты yt
, которые возвращают или принимают данные, необходимо указывать формат.
Чтение таблицы в формате DSV:
yt read //some/table --format dsv
YTsaurus поддерживает следующие форматы представления данных:
Пример
В примерах будет использована данная таблица:
name | uid |
---|---|
Elena | 95792365232151958 |
Denis | 78086244452810046 |
Mikhail | 70609792906901286 |
Ilya | 15696008603902587 |
Oxana | 76840674253209974 |
Alexey | 15943558469181404 |
Roman | 37865805882228106 |
Anna | 35039450424270744 |
Nikolai | 45320538587295288 |
Karina | 20364947097122776 |
YSON
Формат YSON является основным форматом YTsaurus, в нем хранятся табличные данные, атрибуты узлов Кипариса и многие другие объекты. YSON является аналогом формата JSON, но включает понятие атрибутов узла и поддерживает бинарные данные.
Подробная спецификация в разделе YSON.
Для чтения таблицы в формате YSON выполните:
yt read --proxy <cluster-name> --format '<format=pretty>yson' '//home/tutorial/staff_unsorted_sample'
Представление таблицы в формате YSON:
{
"name" = "Elena";
"uid" = 95792365232151958;
};
{
"name" = "Denis";
"uid" = 78086244452810046;
};
{
"name" = "Mikhail";
"uid" = 70609792906901286;
};
{
"name" = "Ilya";
"uid" = 15696008603902587;
};
{
"name" = "Oxana";
"uid" = 76840674253209974;
};
{
"name" = "Alexey";
"uid" = 15943558469181404;
};
{
"name" = "Roman";
"uid" = 37865805882228106;
};
{
"name" = "Anna";
"uid" = 35039450424270744;
};
{
"name" = "Nikolai";
"uid" = 45320538587295288;
};
{
"name" = "Karina";
"uid" = 20364947097122776;
};
Параметры
В скобках указаны значения по умолчанию.
- format (
binary
) — описывает вид YSON, в котором будут сформированы данные. Указание вида имеет значение только при указании выходного по отношению к системе формата, для входного формата все разновидности YSON читаются системой гомогенно:binary
— бинарный,text
— текстовый, без форматирования,pretty
— текстовый, с форматированием.
- skip_null_values (
%false
) - включить пропуск значенийnull
в схематизированных таблицах. По умолчанию все значения записываются. - enable_string_to_all_conversion (
false
) — включить приведение строковых значений к численным и boolean типам. Например,"42u"
преобразуется в42u
, а"false"
преобразуется в%false
. - enable_all_to_string_conversion (
false
) — включить приведение численных и boolean значений к строковому типу. Например, число3.14
превратится в"3.14"
, а%false
в"false"
. - enable_integral_type_conversion (
true
) — включить приведениеuint64
кint64
и наоборот. Обратите внимание, эта опция включена по умолчанию. Если при преобразовании происходит переполнение, то возникает соответствующая ошибка. - enable_integral_to_double_conversion (
false
) — включить приведениеuint64
иint64
кdouble
. Например, целое число42
превратится в дробное число42.0
. - enable_type_conversion (
false
) — включить все опции выше. В большинстве случаев достаточно пользоваться только этой опцией. - complex_type_mode (
named
) — режим представления композитных типов, структур и вариантов,
возможные значенияnamed
илиpositional
, подробнее в разделе. - string_keyed_dict_mode (
positional
) - режим представления словарей со строковыми ключами, возможные значенияnamed
илиpositional
, подробнее в специальном разделе. - decimal_mode (
binary
) — режим представления типаdecimal
,
возможные значенияtext
,binary
, подробнее в разделе. - time_mode (
binary
) — режим представления типовdate
,datetime
,timestamp
, возможные значенияtext
илиbinary
, подробнее в разделе. - uuid_mode (
binary
) — режим представления типаuuid
, возможные значенияbinary
,text_yql
илиtext_yt
подробнее в разделе. - sort_keys (
%false
) — выводить ключи в словарях в сортированном порядке, возможные значения%true
или%false
.
JSON
JSON — широко распространенный формат для отображения структурированных данных.
Работать с JSON удобно, используя популярные инструменты, например jq. Кроме того, нет необходимости устанавливать дополнительные библиотеки для поддержки YSON.
Подробная спецификация JSON.
Основным форматом YTsaurus является YSON. В отличие от JSON он имеет атрибуты. Поэтому для преобразования данных из YSON в JSON необходимо закодировать атрибуты в JSON.
Для этого конвертируйте узел с атрибутами в map-node c двумя ключами:
\$value
— его значением становится весь текущий узел без атрибутов;\$attributes
— его значением становитсяmap
атрибутов.
Например, <attr=10>{x=y}
представляется в виде {"$value": {"x": "y"}, "$attributes": {"attr": 10}}
.
Строки в YTsaurus — YSON-строки — являются байтовыми, в то время как JSON использует кодирование Unicode.
У формата есть настройка encode_utf8
, позволяющая управлять конверсией. encode_utf8
по умолчанию равен %true
.
- encode_utf8=%true
Чтобы преобразовать YSON-строку в JSON-строку, нужно перевести каждый байт в unicode-символ с соответствующим номером и закодировать в UTF-8. Такое преобразование происходит, например, при чтении табличных данных командой read_table
.
При преобразовании JSON-строки в YSON-строку происходит проверка последовательности unicode-символов JSON-строки: каждый из них должен находиться в диапазоне от 0 до 255. Затем они конвертируются в соответствующие байты. Такое преобразование выполняется при записи табличных данных командой write_table
.
Внимание
При encode_utf8=%true
unicode-символы вне диапазона 0..255 в JSON-строке не допускаются.
- encode_utf8=%false
Чтобы преобразовать YSON-строку в JSON-строку требуется, чтобы в YSON-строке находилась последовательность, допустимая UTF-8. Она будет преобразована в unicode-строку JSON.
При преобразовании JSON-строки в YSON-строку выполняется UTF8-кодирование unicode-символов в байтовые последовательности. Такое преобразование выполняется командой write_table
.
Внимание
В общем случае байтовые последовательности в таблицах не всегда являются UTF8-последовательностями. Поэтому при encode_utf8=%false
не все YSON-строки доступны для чтения.
Запись UTF-8 строки:
yt.write_table("//path/to/table", [{"key": "Иван"}], format=yt.JsonFormat(attributes={"encode_utf8": False}))
echo '{"key": "Иван"}{"key":"Иванов"}' | YT_PROXY=<cluster-name> yt write --table "//path/to/table" --format="<encode_utf8=%false>json"
Примечание
При чтении пользователем таблицы в формате JSON каждая запись будет сделана в отдельной строке. При этом формат pretty
не поддерживается.
Чтение таблицы в формате JSON:
yt read --proxy <cluster-name> --format json '//home/tutorial/staff_unsorted_sample'
Представление таблицы в формате JSON:
{"name":"Elena","uid":95792365232151958}
{"name":"Denis","uid":78086244452810046}
{"name":"Mikhail","uid":70609792906901286}
{"name":"Ilya","uid":15696008603902587}
{"name":"Oxana","uid":76840674253209974}
{"name":"Alexey","uid":15943558469181404}
{"name":"Roman","uid":37865805882228106}
{"name":"Anna","uid":35039450424270744}
{"name":"Nikolai","uid":45320538587295288}
{"name":"Karina","uid":20364947097122776}
Параметры
В скобках указаны значения по умолчанию.
- format (
text
) — описывает формат JSON, в котором будут сформированы данные. Имеет значение только при указании выходного по отношению к системе формата. Для входного формата все разновидности JSON читаются системой гомогенно:text
— текстовый без форматирования;pretty
— текстовый с форматированием.
- attributes_mode (
on_demand
) — режим работы с атрибутами:always
— каждый узел превращается в map с\$value
и\$attributes
;never
— атрибуты игнорируются;on_demand
— только узлы с непустыми атрибутами превращаются в map с\$value
и\$attributes
.
- encode_utf8 (
true
) — включить интерпретацию UTF-8 символов в байты с соответствующими номерами. - string_length_limit — ограничение на длину строки в байтах. При превышении лимита строка будет обрезана, а результат записан в виде
{$incomplete: true, $value:...}
. - stringify (
false
) — включить преобразование всех скалярных типов в строки. - stringify_nan_and_infinity (
false
) - включить преобразованиеNan
иInfinity
в строки. Не может быть указан вместе сsupport_infinity
. - support_infinity (
false
) - разрешить значениеNan
в типеdouble
. Не может быть указан вместе сstringify_nan_and_infinity
. - annotate_with_types — включить аннотацию типов
{$type: "uint64", $value: 100500}
. - plain — включить опцию парсера JSON, которая отключает учет логики про специальные ключи
\$attributes
,\$value
,\$type
и разбирает JSON как есть. При включенной опции парсер работает существенно быстрее. - enable_string_to_all_conversion (
false
) — включить приведение строковых значений к численным иboolean
-типам. Например,"42u"
преобразуется в42u
, а"false"
преобразуется в%false
. - enable_all_to_string_conversion (
false
) — включить приведение численных иboolean
-значений к строковому типу. Например, число3.14
превратится в"3.14"
, а%false
в"false"
. - enable_integral_type_conversion (
true
) — включить приведениеuint64
кint64
и наоборот. Если при преобразовании происходит переполнение, возникает соответствующая ошибка. - enable_integral_to_double_conversion (
false
) — включить приведениеuint64
иint64
кdouble
. Например, целое число42
превратится в дробное число42.0
. - enable_type_conversion (
false
) — включить все перечисленные опции. В большинстве случаев достаточно пользоваться только этой опцией.
Внимание
JSON имеет некомпактное представление байтов с номерами 0-32 (а именно \u00XX). При попытке записать длинную строку из таких данных может возникнуть ошибка Out of memory в библиотеке Yajl, так как ограничение на объем памяти равно 2 * row_weight
. В таком случае не рекомендуется использовать формат JSON.
DSV (TSKV)
DSV — Delimiter-Separated Values.
TSKV — Tab-Separated Key-Value.
Формат, широко используемый для хранения логов и работы с ними. DSV и TSKV — это два названия одного и того же формата.
Данный формат поддерживает только плоские записи с произвольным набором колонок и строковыми значениями. Записи разделены символом переноса строки \n
.
Поля в записи разделяются символом табуляции \t
.
Подробнее можно прочитать ниже.
Пример записи: time=10\tday=monday\n
.
Внимание
Формат не поддерживает атрибуты и типизированные значения. В примере 10
будет распознано системой как строка, а не как число.
Чтение таблицы в формате DSV:
yt read --proxy <cluster-name> --format dsv '//home/tutorial/staff_unsorted_sample'
Представление таблицы в формате DSV:
name=Elena uid=95792365232151958
name=Denis uid=78086244452810046
name=Mikhail uid=70609792906901286
name=Ilya uid=15696008603902587
name=Oxana uid=76840674253209974
name=Alexey uid=15943558469181404
name=Roman uid=37865805882228106
name=Anna uid=35039450424270744
name=Nikolai uid=45320538587295288
name=Karina uid=20364947097122776
Чтение таблицы с некоторыми параметрами:
yt read --proxy <cluster-name> --format '<field_separator=";";key_value_separator=":">dsv' '//home/tutorial/staff_unsorted_sample'
Параметры:
В скобках указаны значения по умолчанию.
- record_separator (
\n
) — разделитель записей. - key_value_separator (
=
) — разделитель пары ключ-значение. - field_separator (
\t
) — разделитель полей в записи. - line_prefix (по умолчанию колонка отсутствует) — обязательная колонка в начале каждой записи.
- enable_escaping (
true
) — включить escaping записей. - escape_carriage_return (
false
) — включить escaping символа\r
. - escaping_symbol (
\
) — символ экранирования. - enable_table_index (
false
) – включить вывод индекса входной таблицы. - table_index_column (
@table_index
) – название колонки, в которой будет находиться индекс таблицы. - enable_string_to_all_conversion (
false
) — включить приведение строковых значений к численным и boolean-типам. Например,"42u"
преобразуется в42u
, а"false"
преобразуется в%false
. - enable_all_to_string_conversion (
false
) — включить приведение численных и boolean-значений к строковому типу. Например, число3.14
преобразуется в"3.14"
, а%false
в"false"
. - enable_integral_type_conversion (
true
) — включить приведениеuint64
кint64
и наоборот. Если при преобразовании происходит переполнение, возникает соответствующая ошибка. - enable_integral_to_double_conversion (
false
) — включить приведениеuint64
иint64
кdouble
. Например, целое число42
преобразуется в дробное число42.0
. - enable_type_conversion (
false
) — включить все перечисленные выше опции. В большинстве случаев достаточно пользоваться только этой опцией.
Примечание
Практически произвольная строка является валидной DSV-записью. Если после ключа нет key-value разделителя, поле игнорируется.
SCHEMAFUL_DSV
Формат является разновидностью DSV. При использовании SCHEMAFUL_DSV данные формируются в виде набора значений, разделенных табами.
У формата есть обязательный атрибут columns
, в котором через точку с запятой необходимо задать имена интересующих колонок. Если хотя бы в одной из записей отсутствует значение одной из колонок, возникнет ошибка (смотрите missing_value_mode).
Например, если в таблице есть две записи {a=10;b=11} {c=100}
и указан формат <columns=[a]>schemaful_dsv
, возникнет ошибка вида Column "a" is in schema but missing
.
Если в таблице будет только первая запись, на вход джобу пришла бы запись10
.
Примечание
При работе с YTsaurus CLI необходимо писать атрибуты в кавычках. Например: --format="<columns=[a;b]>schemaful_dsv"
Чтение таблицы в формате SCHEMAFUL_DSV:
yt read --proxy <cluster-name> --format '<columns=[name;uid]>schemaful_dsv' '//home/tutorial/staff_unsorted_sample'
Представление таблицы в формате SCHEMAFUL_DSV:
Elena 95792365232151958
Denis 78086244452810046
Mikhail 70609792906901286
Ilya 15696008603902587
Oxana 76840674253209974
Alexey 15943558469181404
Roman 37865805882228106
Anna 35039450424270744
Nikolai 45320538587295288
Karina 20364947097122776
Параметры:
В скобках указаны значения по умолчанию.
- record_separator (
\n
) — разделитель записей. - field_separator (
\t
) — разделитель полей. - enable_table_index (
false
) – включить печать переключения таблиц во входных данных. - enable_escaping (
true
) – включает escaping служебных символов\n
,\t
и\
. - escaping_symbol (
\
) – символ экранирования. - columns – список колонок, которые будут форматироваться, например
<columns=[columnA;columnB]>schemaful_dsv
. - missing_value_mode (
fail
) — поведение при отсутствии значения –NULL
:skip_row
— пропустить строку;fail
— прекратить выполнение операции, если указанной колонки нет в одной из строк;print_sentinel
— вместо отсутствующих значений задатьmissing_value_sentinel
, который по умолчанию равен пустой строке.
- missing_value_sentinel (
пустая строка
) — значение отсутствующей колонки для режима print_sentinel. - enable_column_names_header (
false
) — может быть использовано только при формировании данных в формате SCHEMAFUL_DSV, но не при разборе таких данных. Если значение равно%true
, то в первой строке вместо значений будут имена колонок. Важно - имена колонок могут дублироваться в теле ответа при включенном параллельном чтении или ретраях. - enable_string_to_all_conversion (
false
) — включить приведение строковых значений к численным и boolean-типам. Например,"42u"
преобразуется в42u
, а"false"
преобразуется в%false
. - enable_all_to_string_conversion (
false
) — включить приведение численных и boolean-значений к строковому типу. Например, число3.14
превратится в"3.14"
, а%false
в"false"
. - enable_integral_type_conversion (
true
) — включить приведениеuint64
кint64
и наоборот. Обратите внимание, эта опция включена по умолчанию. Если при преобразовании происходит переполнение, то возникает соответствующая ошибка. - enable_integral_to_double_conversion (
false
) — включить приведениеuint64
иint64
кdouble
. Например, целое число42
превратится в дробное число42.0
. - enable_type_conversion (
false
) — включить все перечисленные выше опции. В большинстве случаев достаточно пользоваться только этой опцией.
ARROW
Arrow (apache arrow) - бинарный формат, разработанный как универсальный стандарт для эффективного представления и обмена поколоночными данными в памяти между различными системами.
Преимущества формата:
-
В отличие от строкового представления, где данные каждой строки хранятся вместе, arrow организует данные в столбцы. Это позволяет более эффективно выполнять некоторые аналитические запросы.
-
Arrow поддерживает сложные типы данных, такие как структуры, списки, словари и другие.
Arrow в YTsaurus
При чтении таблицы в формате arrow возвращается конкатенация нескольких IPC Streaming Format потоков.
<SCHEMA>
<DICTIONARY 0>
...
<DICTIONARY k - 1>
<RECORD BATCH 0>
...
<DICTIONARY x DELTA>
...
<DICTIONARY y DELTA>
...
<RECORD BATCH n - 1>
<EOS 0x00000000>
<SCHEMA>
...
<EOS 0x00000000>
...
<EOS 0x00000000>
Возвращается несколько сконкатенированных потоков, а не один общий из-за того, что в YTsaurus одна и та же колонка может храниться по-разному в разных чанках. Например, данные колонки могут храниться как явно целиком, так и в виде словаря (аналогично словарю в arrow). При представлении данных в arrow формате мы сохраняем кодировку в виде словаря, и отдаем несколько сконкатенированных потоков, если какая-то колонка в одном чанке закодирована целиком, а в другом как словарь.
Ограничения и особенности:
-
Чтение и запись можно производить только со схематизированными таблицами.
-
Рекомендуется читать в arrow таблицы с поколоночным форматом хранения чанков
optimize_for = scan
, чтобы чтение было эффективно.
Внимание
Запись в arrow пока не оптимизирована для таблиц с поколоночным форматом хранения чанков, происходит двойная трансформация данных, из поколоночного представления трансформируется в построчное и обратно.
Типы
Для чтения таблиц сейчас поддержаны такие типы:
string
отображается в arrow::binaryinteger
отображается в какой-то из arrow::integer в зависимости от
битности и знакаboolean
отображается в arrow::boolfloat
отображается в arrow::floatdouble
отображается в arrow::doubledate
отображается в arrow::date32datetime
отображается в arrow::date64timestamp
отображается в arrow::timestampinterval
отображается в arrow::int64cложные типы
представляются в виде arrow::binary, где хранится yson представление этих типов
На запись поддержаны те же типы, что и на чтение, а также дополнительно поддержаны:
- arrow::list представляется, как
list
- arrow::map представляется, как
dict
- arrow::struct представляется, как
struct
Другие особенности работы с типами:
-
При чтении таблицы почти любой из типов может прийти, как arrow::dictionary, где элементы словаря будут значениями, которые встречаются в колонке, а индексы указывают на порядок значений, подробнее тут.
-
формат arrow поддерживает одну вложенность optional, более глубокая вложенность при чтении будет возвращена бинарным типом, так же как и для остальных сложных типов.
Пример операций
Чтение таблицы в arrow:
yt.read_table("//path/to/table", format=yt.format.ArrowFormat(), raw=True)
yt read --table "//path/to/table" --format arrow
Map операция с arrow:
yt map --input-format arrow --output-format arrow --src "//path/to/input_table" "cat" --dst '<schema=[{name=item_1;type=int64};{name=item_2;type=string}]>//path/to/output_table'
Операции с несколькими таблицами
Если на вход операции в формате arrow передать несколько таблиц, то внутри операции будет получен поток так же в виде конкатенации нескольких IPC Streaming Format потоков, где каждая часть может принадлежать одной из таблиц. Индекс таблицы передается в виде метаданных схемы с именем TableId
, подробнее о метаданных в arrow можно почитать тут
PARQUET
Поддержана работа с parquet из командной строки:
- dump-parquet позволяет скачать таблицу локально в виде файла в формате parquet.
- upload-parquet позволяет загрузить в YT локальный файл в формате parquet в виде статической схематизированной таблицы.
PROTOBUF
Protobuf - протокол передачи структурированных данных для работы с таблицами в С++ API.
Подробнее можно прочитать в разделе Protobuf.