我正在尝试使用新密钥将修改后的文档插回到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)
以下是查询和当前的数据:
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'
答案 0 :(得分:13)
“没有可行的替代方法”意味着某个键的数据类型与该列族列的模式不匹配,遗憾的是它在错误消息中并未明确地说明。
在我的例子中,meta的数据类型是:
map<text,text>
因此在插入时没有被认为是错误的值。我通过在插入之前用空dict替换None来解决问题:
if current['meta'] is None:
current['meta'] = dict()
CQL驱动程序接受空dict fine作为地图类型的新值,而不允许None,即使查询map列,如果为空,则返回None。
返回None并且不接受None感觉不直观,所以后来我决定为cursor.fetchone()创建自定义包装器,它返回列的映射而不是列的列表,并检查MapType,ListType或SetType已退回无。如果没有None值,则用空dict(),list()或set()替换它们,以避免将修改后的数据插回Cassandra时出现的问题。这看起来效果很好。