Python 是什么导致 Cassandra CQL 出现“在输入‘无’时没有可行的替代方案”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14897599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:47:34  来源:igfitidea点击:

What causes "no viable alternative at input 'None'" error with Cassandra CQL

pythoncassandracql

提问by Fuu

I'm attempting to insert a modified document back to Cassandra DB with a new key. I'm having hard time figuring out what is the issue the error message is pointing at. When looking for others that have had similar problems the answers seem to be related to the keys, and in my case the None is just a value of few of the keys. How do I solve this issue?

我正在尝试使用新密钥将修改后的文档插入回 Cassandra DB。我很难弄清楚错误消息所指的问题是什么。在寻找其他有类似问题的人时,答案似乎与键有关,在我的情况下, None 只是少数键的值。我该如何解决这个问题?

keys = ','.join(current.keys())
params = [':' + x for x in current.keys()]
values = ','.join(params)

query = "INSERT INTO wiki.pages (%s) Values (%s)" % (keys, values)
query = query.encode('utf-8')
cursor.execute(query, current)

Here's the data for query and current:

这是查询和当前的数据:

INSERT INTO wiki.pages (changed,content,meta,attachment,revision,page,editor) 
VALUES (:changed,:content,:meta,:attachment,:revision,:page,:editor)

{
    u'changed': '2013-02-15 16:31:49', 
    u'content': 'Testing', 
    u'meta': None, 
    u'attachment': None,    
    u'revision': 2, 
    u'page': u'FrontPage', 
    u'editor': 'Anonymous'
}

This fails with the following error:

这失败并出现以下错误:

cql.apivalues.ProgrammingError: 
Bad Request: line 1:123 no viable alternative at input 'None'

采纳答案by Fuu

The "no viable alternative" means that the data type for some key doesn't match the schema for that column family column, unfortunately it doesn't plainly say that in the error message.

“没有可行的替代方案”意味着某些键的数据类型与该列族列的架构不匹配,不幸的是,它没有在错误消息中明确说明这一点。

In my case the data type for meta was:

在我的情况下,meta 的数据类型是:

map<text,text> 

for this reason None was considered a bad value at insertion time. I fixed the problem by replacing the None with an empty dict prior to insert:

出于这个原因,在插入时 None 被认为是一个不好的值。我通过在插入之前用空字典替换 None 来解决这个问题:

if current['meta'] is None:
    current['meta'] = dict()

The CQL driver accepts empty dict fine as new value for a map type, while None is not allowed, even though querying the map column returns None if it is empty.

CQL 驱动程序接受空字典作为地图类型的新值,而 None 是不允许的,即使查询地图列如果为空则返回 None 。

Returning None and not accepting None did not feel intuitive, so later I decided to create custom wrapper for cursor.fetchone() that returns a map of columns instead of a list of columns, and also checks if MapType, ListType or SetType has returned None. If there are None values, it replaces them with empty dict(), list() or set() to avoid issues like the one I had when inserting modified data back to Cassandra. This seems to work nicely.

返回 None 和不接受 None 感觉不直观,所以后来我决定为 cursor.fetchone() 创建自定义包装器,返回列映射而不是列列表,并检查 MapType、ListType 或 SetType 是否已返回 None . 如果有 None 值,它会用空的 dict()、list() 或 set() 替换它们,以避免我在将修改后的数据插入回 Cassandra 时遇到的问题。这似乎工作得很好。