什么导致"没有可行的替代输入'无''错误与Cassandra CQL

Fuu*_*Fuu 10 python cql cassandra

我正在尝试使用新密钥将修改后的文档插回到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)
Run Code Online (Sandbox Code Playgroud)

这是查询和当前的数据:

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'
}
Run Code Online (Sandbox Code Playgroud)

此操作失败,并显示以下错误:

cql.apivalues.ProgrammingError: 
Bad Request: line 1:123 no viable alternative at input 'None'
Run Code Online (Sandbox Code Playgroud)

Fuu*_*Fuu 13

"没有可行的替代方案"意味着某个键的数据类型与该列族列的模式不匹配,遗憾的是它在错误消息中没有明确说明.

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

map<text,text> 
Run Code Online (Sandbox Code Playgroud)

因此,在插入时没有被认为是错误的值.我通过在插入之前用空dict替换None来解决问题:

if current['meta'] is None:
    current['meta'] = dict()
Run Code Online (Sandbox Code Playgroud)

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

返回None并且不接受None并不感觉直观,所以后来我决定为cursor.fetchone()创建自定义包装器,它返回列的映射而不是列的列表,并检查MapType,ListType或SetType是否已返回None .如果没有None值,则用空dict(),list()或set()替换它们,以避免将修改后的数据插回Cassandra时出现的问题.这看起来效果很好.

  • FWIW,"没有可行的替代方案"在技术上是解析错误,而不是类型错误. (3认同)
  • 要添加@jbellis所说的,当我将字符串常量连接到多行(对于我准备好的语句)时,这通常会发生在我身上,而我忘记确保标识符/​​关键字两边都有空格.例如,`SELECT*FROM tablenameWHERE foo =?`将导致`foo`没有可行的选择,因为它期望`WHERE`关键字而不是标识符.(如果它暗示了它的期望,会很好.) (2认同)