python - 如何将字典绑定(bind)为准备好的查询参数?

标签 python python-2.7 cassandra

我想将 dict 绑定(bind)到准备好的语句的参数,但我似乎无法弄清楚语法。让我困惑的是,如果我使用 positional parameters ,它就会起作用。没有准备好的声明。

看一下这个例子:

from cassandra.cluster import Cluster


def works():
    id = '1'
    mydict = {'count': 1, 'value': 3}

    updateStmt = "insert into test.prep_test (id, mydict) values (%s, %s);"

    session.execute(updateStmt, (id, mydict))


def doesntwork():
    id = '2'
    mydict = {'count': 1, 'value': 3}

    updateStmt = "insert into test.prep_test (id, mydict) values (?, ?);"
    prep = session.prepare(updateStmt)

    session.execute(prep, [id, mydict])


if __name__ == "__main__":
    cluster = Cluster(['127.0.0.1'])
    session = cluster.connect('test')

    session.execute(
        'create table if not exists test.prep_test (  id ascii, mydict MAP<ascii,decimal>, PRIMARY KEY (id));')

    works()
    doesntwork()

    session.shutdown()
    cluster.shutdown()

works() 方法可以很好地插入数据。但是,doesntwork() 方法失败并出现以下错误:

Traceback (most recent call last):
  File "/new.py", line 31, in <module>
    doesntwork()
  File "/new.py", line 20, in doesntwork
    session.execute(prep, [id, mydict])
  File "cassandra/cluster.py", line 1569, in cassandra.cluster.Session.execute (cassandra/cluster.c:26912)
  File "cassandra/cluster.py", line 1619, in cassandra.cluster.Session.execute_async (cassandra/cluster.c:27219)
  File "cassandra/cluster.py", line 1632, in cassandra.cluster.Session._create_response_future (cassandra/cluster.c:27553)
  File "cassandra/query.py", line 411, in cassandra.query.PreparedStatement.bind (cassandra/query.c:5947)
  File "cassandra/query.py", line 536, in cassandra.query.BoundStatement.bind (cassandra/query.c:7678)
TypeError: Received an argument of invalid type for column "mydict". Expected: <class 'cassandra.io.asyncorereactor.MapType(AsciiType, DecimalType)'>, Got: <type 'dict'>; (Non-Decimal type received for Decimal value)

Process finished with exit code 1

最佳答案

当您在 Works() 情况下运行它时,驱动程序在幕后使用字符串替换来生成以下查询,并将其提交给 C*

'''insert into test.prep_test1 (id, mydict) values ('1', {'count': 1, 'value': 3});'''

这基本上是一个愚蠢的字符串替换。

在第二种情况下,服务器和客户端之间传递多条消息。首先准备一份声明。有关此准备好的语句的上下文与 C* 服务器共享。这里的验证将更加严格,因为与查询关联的上下文对于驱动程序和服务器来说是已知的。

您可以通过在查询中使用适当的类型来解决此问题。在这种情况下,将 mydict 绑定(bind)到上面建议的 Decimal 值。

mydict = {'count': Decimal(1), 'value': Decimal(3)}

或者,您可以在表中使用 int 类型,如下所示。

 'create table if not exists test.prep_test (  id ascii, mydict MAP<ascii,int>, PRIMARY KEY (id));')

您可能会说驱动程序应该能够从 int 或 float 类型映射到十进制,但这不是它现在的工作方式。

关于python - 如何将字典绑定(bind)为准备好的查询参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34730897/

相关文章:

python - Kivy 未显示在 Raspberry Pi 3 上运行的 Window

python - 神经网络偏差训练

python - 使用可变模式创建 Pyspark 数据框

elasticsearch - 启动Elassandra-使用Elasticsearch的Cassandra失败,path.home未配置

mysql - 关于社交网站DB的问题

database - 具有相同节点的 Cassandra 多个数据中心

Python 绑定(bind)到 ImageMagick

python - 如何提取具有最大值的 Django 对象?

python - 将请求放在 curl 中,但不放在 Python 中

python - 如何使用 lxml 创建文档的子集?