【问题标题】:What causes "no viable alternative at input 'None'" error with Cassandra CQL是什么导致 Cassandra CQL 出现“输入‘无’时没有可行的替代方案”错误
【发布时间】:2013-01-31 14:22:43
【问题描述】:

我正在尝试使用新密钥将修改后的文档插入回 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'

【问题讨论】:

    标签: python cassandra cql


    【解决方案1】:

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

    在我的例子中,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 值,它将用空的 dict()、list() 或 set() 替换它们,以避免像我在将修改后的数据插入回 Cassandra 时遇到的问题。这似乎工作得很好。

    【讨论】:

    • FWIW,“没有可行的替代方案”在技术上是解析错误,而不是类型错误。
    • 补充一下@jbellis所说的,当我跨多行连接字符串常量(对于我准备好的语句)并且我忘记确保两边都有空格时,这通常发生在我身上我的标识符/关键字。例如,SELECT * FROM tablenameWHERE foo = ? 将导致 no viable alternative at: foo,因为它需要 WHERE 关键字而不是标识符。 (如果它暗示了它的期望,那就太好了。)
    • FWIW,“没有可行的替代方案”来自 ANTLR,所以如果您需要深入研究,请获取 ANTLR 语法。
    猜你喜欢
    • 1970-01-01
    • 2016-01-14
    • 2013-01-23
    • 1970-01-01
    • 2015-07-21
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多