Невозможно скопировать данные UTF-8 в ScyllaDB с помощью cqlsh - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь скопировать большой набор данных из Postgresql в ScyllaDB, который должен быть совместим с Cassandra.

Это то, что я пытаюсь:

psql <db_name> -c "COPY (SELECT row_number() OVER () as id, * FROM ds.my_data_set LIMIT 20) TO stdout WITH (FORMAT csv, HEADER, DELIMITER ';');" \
 | \
CQLSH_HOST=172.17.0.3 cqlsh -e 'COPY test.mytable (id, "Ist Einpöster", [....]) FROM STDIN WITH DELIMITER = $$;$$ AND HEADER = TRUE;'

Я получаю скрытую ошибку без трассировки стека:

: 1: кодек «ascii» не может декодировать байт 0xc3 в позиции 9: порядковый номер не в диапазоне (128)

Мои данные и имена столбцов, в том числе уже в созданной таблице в ScyllaDB, содержат значения с текстом на немецком языке.Это не ASCII, но я не нашел нигде, чтобы установить кодировку, и везде, где я смотрел, казалось, уже используется utf-8.Я также попытался this и увидел в окрестности строки 1135 что, и изменил его в моем локальном cqlsh (используя vim $(which cqlsh)), но это не дало никакого эффекта.

I 'м, используя cqlsh 5.0.1, устанавливается с помощью пипа.(странно, это было pip install cqlsh==5.0.4)

Я также попробовал cqlsh из образа докера, который я использовал для установки ScyllaDB , и он имеет точно такую ​​же ошибку.


Как и предполагалось, я передал данные в файл:

psql <db_name> -c "COPY (SELECT row_number() OVER (), * FROM ds.my_data_set ds) TO stdout WITH (FORMAT csv, HEADER);" | head -n 1 > test.csv

Я сократил их до первого ряда (заголовок CSV).Пропуск его до cqlsh заставил его плакать с той же ошибкой.Затем, используя интерактивную оболочку python3.5, я сделал это:

>>> with open('test.csv', 'rb') as fp:
...   data = fp.read()
>>> data
b'row_number,..... Ist Einp\xc3\xb6ster ........`

Итак, мы находимся \xc3 во плоти.Это UTF-8?

>>> data.decode('utf-8')
'row_number,....... Ist Einpöster ........`

Да, это utf-8.Так как же происходит ошибка?

>>> data.decode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 336: ordinal not in range(128)

Тот же текст ошибки, так что, вероятно, это тоже Python, но без трассировки стека, я понятия не имею, где это происходит, и кодировки по умолчанию utf-8.Я попытался переопределить значение по умолчанию с utf-8, но ничего не изменилось.Тем не менее, где-то что-то пытается декодировать поток с использованием ASCII.

Это locale на сервере / клиенте:

LANG=
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

Кто-то в Slack предложил этот ответ UnicodeDecodeError: кодек «ascii» не может декодировать байт 0xd1 в позиции 2: порядковый номер не находится в диапазоне (128) Как только я добавил последние 2 строки в cqlsh.py в начале, он прошел проблему с декодированием, нотот же столбец был объявлен недействительным с другой ошибкой:

: 1: недопустимое имя столбца Ist Einpöster

примечание:

На данный момент я потерял интерес к этому тесту, и я просто пытаюсь не задавать вопрос без ответа, поэтому, пожалуйста, извините за время ожидания.Когда я пробовал это в качестве аналитического движка в сочетании со Spark в качестве источника данных для Tableau, я нашел «лучшие» альтернативы, такие как Vertica и ClickHouse.«Лучше», потому что у них обоих есть ограничения.

Как мне завершить этот импорт?

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Сначала я бы попытался устранить все дополнительные сложности, которые у вас есть.Попробуйте сбросить несколько строк в CSV, а затем загрузить его в Scylla, используя COPY

0 голосов
/ 29 ноября 2018

Что это было?

Запрос, переданный в качестве аргумента, содержал список столбцов, который содержал этот столбец с не-ASCII-символом.В какой-то момент cqlsh проанализировал их как ascii, а не utf-8, что привело к этой ошибке.

Как это было исправлено?

Первая попытка былаДобавьте эти 2 строки в cqlsh:

reload(sys)
sys.setdefaultencoding('utf-8')

, но это все еще не позволило сценарию работать с этим столбцом.

Вторая попытка состояла в том, чтобы просто передать запрос из файла.Если вы не можете, знайте, что bash поддерживает подстановку процессов, поэтому вместо этого:

cqlsh -f path/to/query.cql

вы можете иметь

cqlsh -f <(echo "COPY .... FROM STDIN;")

И это все замечательно, за исключением того, что это не такработать тоже.cqlsh понимает stdin как «интерактивный», из приглашения, а не по каналу. В результате он ничего не импортирует.Можно просто создать файл и загрузить его из файла, но это дополнительный шаг, который может занять минуты или часы, в зависимости от размера данных.
К счастью, в системах POSIX есть такие виртуальные файлы, как '/ dev / stdin'Таким образом, приведенная выше команда эквивалентна следующей:

cqlsh -f <(echo "COPY .... FROM '/dev/stdin';")

за исключением того, что cqlsh теперь думает, что у вас действительно есть файл, и читает его как файл, так что вы можете передавать свои данные и быть счастливыми.

Это, вероятно, сработает, но по какой-то причине я получил последний удар:

cqlsh.sql: 2: Не удалось импортировать 15 строк: InvalidRequest - Ошибка с сервера: code = 2200[Invalid query] message = "Пакет слишком большой", повторю позже, попытка 4 из 5

Мне кажется забавным, что 15 строк слишком много для механизма распределенного хранения.И вполне вероятно, что это опять-таки ограничение движка, связанное с юникодом, и просто неправильное сообщение об ошибке.Или я не прав.Тем не менее, на первый вопрос был дан ответ с БОЛЬШОЙ помощью парней из Slack.

0 голосов
/ 27 ноября 2018

Я не вижу, чтобы вы когда-нибудь получили ответ на это.UTF-8 должен быть значением по умолчанию.

Вы пробовали --encoding?

Документы: https://docs.scylladb.com/getting-started/cqlsh/

Если вы не получили ответ здесь, хотели бы вы задать его на нашем слабом канале ?

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