15

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

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)

这是查询和当前的数据:

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'
}

这失败并出现以下错误:

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

1 回答 1

15

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

在我的例子中,meta 的数据类型是:

map<text,text> 

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

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

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

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

于 2013-02-15T15:27:42.113 回答