我想将 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/