Каков правильный формат CSV для кортежей при загрузке данных с помощью DSBulk?

Недавно я начал использовать Cassandra для своего нового проекта и провел нагрузочное тестирование.

У меня есть сценарий, в котором я выполняю загрузку dsbulk с использованием CSV следующим образом:

$ dsbulk load -url <csv path> -k <keyspace> -t <table> -h <host> -u <user> -p <password> -header true -cl LOCAL_QUORUM

Мои записи в CSV-файле выглядят так:

userid birth_year created_at                  freq
1234   1990       2023-01-13T23:27:15.563Z    {1234:{"(1, 2)": 1}}

Типы столбцов,

userid bigint PRIMARY KEY,
birth_year int,
created_at timestamp,
freq map<bigint, frozen<map<frozen<tuple<tinyint, smallint>>, smallint>>>

Проблема в том, что для столбца freq я пробую разные способы установки значения в csv, как показано ниже, но не могу вставить строку, используя dsbulk

  1. Скажем, если я установлю частоту как {1234:{[1, 2]: 1}}, com.datastax.oss.dsbulk.workflow.commons.schema.InvalidMappingException: не удалось сопоставить частоту поля с частотой переменной; преобразование из типа Java java.lang.String в тип CQL Map (BIGINT => Map (Tuple (TINYINT, SMALLINT) => SMALLINT, не заморожено), не заморожено) для исходного значения: {1234: {[1,2] : 1}} Причина: java.lang.IllegalArgumentException: не удалось разобрать ‘{1234:{[1, 2]: 1}}’ как Json Причина: com.fasterxml.jackson.core.JsonParseException: неожиданный символ («[» (код 91)): ожидался либо допустимый символ имени (для имени без кавычек), либо двойная кавычка (для кавычек) для начала имени поля в [Источник: (Строка) "{1234: {[1, 2]: 1}}"; строка: 1, столбец: 9]

  2. Если я установлю частоту как {\"1234\":{\"[1, 2]\":1}},
    java.lang.IllegalArgumentException: ожидается, что запись будет содержать 4 поля, но найдено 5.

  3. Если я установлю частоту как {1234:{"[1, 2]": 1}} or {1234:{"(1, 2)": 1}},
    Источник: 1234,80,2023-01-13T23:27:15.563Z,"{1234:{""[1, 2]"": 1}}" java.lang.IllegalArgumentException: ожидается, что запись будет содержать 4 поля, но найдена 5.

Но в команде COPY FROM TABLE значение частоты {1234:{[1, 2]:1}} вставляется в БД без ошибок, значение в БД выглядит так {1234: {(1, 2): 1}}

Я предполагаю, что JSON не принимает массив (кортеж) в качестве ключа, когда я пытаюсь использовать dsbulk? Может кто подскажет в чем проблема и как это исправить? Ценю вашу помощь.

Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При загрузке данных с помощью DataStax Bulk Loader (DSBulk) формат CSV для типа CQL tuple отличается от формата, используемого командой COPY ... FROM, поскольку DSBulk использует другой парсер.

Форматирование данных CSV в вашем случае особенно сложно, поскольку столбец содержит несколько вложенных коллекций CQL.

InvalidMappingException

Парсер JSON, используемый DSBulk, не принимает круглые скобки () при заключении кортежей. Он также ожидает, что кортежи будут заключены в двойные кавычки, иначе вы получите такие ошибки, как:

com.datastax.oss.dsbulk.workflow.commons.schema.InvalidMappingException: \
  Could not map field ... to variable ...; \
  conversion from Java type ... to CQL type ... failed for raw value: ...
   ...
Caused by: java.lang.IllegalArgumentException: Could not parse '...' as Json
   ...
Caused by: com.fasterxml.jackson.core.JsonParseException: \
  Unexpected character ('(' (code 91)): was expecting either valid name character \
  (for unquoted name) or double-quote (for quoted) to start field name
   ...

"

Поскольку значения для кортежей содержат запятую (IllegalArgumentException) в качестве разделителя, DSBulk неправильно анализирует строки и считает, что каждая строка содержит больше полей, чем ожидалось, и выдает ,, например:

java.lang.IllegalArgumentException: Expecting record to contain 2 fields but found 3.

Решение

Чтобы было проще, вот схема таблицы, которую я использую в качестве примера:

CREATE TABLE inttuples (
    id int PRIMARY KEY,
    inttuple map<frozen<tuple<tinyint, smallint>>, smallint>
)

В этом примере файла CSV я использовал символ вертикальной черты (IllegalArgumentException) в качестве разделителя:

id|inttuple
1|{"[2,3]":4}

Вот еще один пример, в котором табуляция используется в качестве разделителя:

id      inttuple
1       {"[2,3]":4}

Обратите внимание, что вам нужно будет указать разделитель с помощью | или -delim '|' при запуске DSBulk. Ваше здоровье!


👉 Пожалуйста, поддержите сообщество Apache Cassandra, наведя указатель мыши на тег cassandra и нажав кнопку -delim '\t'. 🙏 Спасибо!

Большое спасибо, Эрик, за то, что изучил это и дал четкое объяснение. Позвольте мне попробовать этот подход и обновить этот форум (при необходимости).

Senthil 22.01.2023 00:51

Другие вопросы по теме