首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用cqlsh将UTF-8数据复制到ScyllaDB。

无法使用cqlsh将UTF-8数据复制到ScyllaDB。
EN

Stack Overflow用户
提问于 2018-11-22 16:38:18
回答 4查看 977关注 0票数 1

我正在尝试将一个大型数据集从Postgresql复制到ScyllaDB,这应该与Cassandra兼容。

这就是我想要的:

代码语言:javascript
复制
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‘编解码器无法解码位置9的字节0xc3 :序数不在范围内(128)

我的数据和列名,包括已经在ScyllaDB中创建的表中的列名,包含了带有德语文本的值。它不是ASCII,但我还没有找到设置编码的地方,而且我所看到的任何地方都似乎已经在使用utf-8了。我也尝试了,并在第1135行附近看到了它,并在本地cqlsh中更改了它(使用vim $(which cqlsh)),但没有效果。

我使用的是cqlsh 5.0.1,安装使用的是pip。(奇怪的是是pip install cqlsh==5.0.4)

我也尝试了cqlsh用于安装ScyllaDB的docker映像,它有完全相同的错误。

正如建议的那样,我将数据传输到一个文件中:

代码语言:javascript
复制
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交互式shell,我完成了以下操作:

代码语言:javascript
复制
>>> with open('test.csv', 'rb') as fp:
...   data = fp.read()
>>> data
b'row_number,..... Ist Einp\xc3\xb6ster ........`

所以我们到了,\xc3在肉体里。是UTF-8吗?

代码语言:javascript
复制
>>> data.decode('utf-8')
'row_number,....... Ist Einpöster ........`

是的,是utf-8。那么,错误是如何发生的呢?

代码语言:javascript
复制
>>> 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

代码语言:javascript
复制
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

斯拉克上有人提出了这个答案-- UnicodeDecodeError:'ascii‘编解码器不能解码位置2的字节0xd1 :序数不在范围内(128个) --我在cqlsh.py中添加了最后2行--它通过了解码问题,但是同一列被报告无效,还有另一个错误:

*1:无效列名Ist Einp ster

附带说明:

现在我对这个测试失去了兴趣,我只是想不出一个没有答案的问题,所以请原谅等待的时间。当我尝试将它作为一个分析引擎,再加上Spark,作为Tableau的数据源时,我找到了“更好”的替代方案,比如Vertica和ClickHouse。“更好”,因为两者都有局限性。

如何完成此导入?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-11-29 16:11:47

,那是什么?

作为参数传入的查询包含列列表,其中包含具有非ASCII字符的列。在某种程度上,cqlsh将这些解析为ascii而不是utf-8,这导致了这个错误。

是怎么修好的?

第一次尝试是在cqlsh中添加这2行

代码语言:javascript
复制
reload(sys)
sys.setdefaultencoding('utf-8')

但这仍然使脚本无法使用该列。

第二次尝试是简单地从文件中传递查询。如果不能,请知道bash支持进程替换,所以不要这样:

代码语言:javascript
复制
cqlsh -f path/to/query.cql

你可以拥有

代码语言:javascript
复制
cqlsh -f <(echo "COPY .... FROM STDIN;")

这一切都很好,除了它也不起作用。cqlsh从提示符中将stdin理解为“交互式”,而不是用管道输入。其结果是它没有导入任何东西。您可以创建一个文件,并从该文件加载它,但这是一个额外的步骤,可能需要几分钟或几个小时,这取决于数据大小。

幸运的是,POSIX系统具有'/dev/stdin‘这样的虚拟文件,因此上面的命令相当于:

代码语言:javascript
复制
cqlsh -f <(echo "COPY .... FROM '/dev/stdin';")

除了cqlsh现在认为您实际上有一个文件,它读取它像一个文件,所以您可以管道您的数据和高兴。

这可能有用,但出于某种原因,我得到了最后的一击:

cqlsh.sql:2:Failed导入15行: InvalidRequest -从服务器错误: code=2200无效查询message=“批处理太大”,稍后将重试,尝试5中的4。

我认为对于分布式存储引擎来说,15行太多了,这是很有趣的。这很可能是来自与unicode相关的引擎的一些限制,只是一个错误的错误消息。否则我就错了。尽管如此,最初的问题还是得到了回答,在斯拉克的一些人的帮助下。

票数 2
EN

Stack Overflow用户

发布于 2018-11-27 18:35:37

我看不出你对此有什么答案。默认为UTF-8。

你试过--encoding了吗?

博士:https://docs.scylladb.com/getting-started/cqlsh/

如果你在这里没有得到答复,你愿意在我们的松弛通道上问吗?

票数 0
EN

Stack Overflow用户

发布于 2018-11-27 19:21:27

我会努力消除所有额外的复杂性,你在那里首先。尝试将几行转储到CSV中,然后使用COPY将其加载到锡拉。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53435179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档