使用python驱动程序在Cassandra中插入元组字段

使用python驱动程序在Cassandra中插入元组字段,python,cassandra,tuples,Python,Cassandra,Tuples,各位, 我在通过DataStax提供的python驱动程序将数据插入Cassandra表上的元组值字段时遇到问题 要么我不知道如何正确地将tuple参数传递给会话。执行命令,要么驱动程序在内部以错误的方式将tuple发送给Cassandra,因为在cqlsh会话中执行相同的插入操作可以正常工作 在代码和cqlsh中,不涉及元组而涉及列表的等效插入都可以正常工作 我使用的是Python 2.7.10和cassandra驱动程序3.7.1。Python执行过程中引发的错误是InvalidReques

各位,

我在通过DataStax提供的
python驱动程序将数据插入Cassandra表上的元组值字段时遇到问题

要么我不知道如何正确地将tuple参数传递给
会话。执行
命令,要么驱动程序在内部以错误的方式将tuple发送给Cassandra,因为在
cqlsh
会话中执行相同的插入操作可以正常工作

在代码和
cqlsh
中,不涉及元组而涉及列表的等效插入都可以正常工作

我使用的是Python 2.7.10和cassandra驱动程序3.7.1。Python执行过程中引发的错误是
InvalidRequest:error from server:code=2200[Invalid query]message=“Invalid list literal for tuplefield of type freezed”

我在下面粘贴了一个复制我看到的问题的最小工作代码。有人能帮我弄清楚我是否做错了什么吗

(注意:我已经尝试将一个普通的列表传递给
会话。执行
代替tuple参数,但也没有成功。)

多谢各位

'''
    Run with:
        python 2.7.10
        cassandra-driver==3.7.1 installed
'''

from cassandra.cluster import Cluster

if __name__=='__main__':

    serverAddress='SERVER_ADDRESS'
    keyspacename='tupletests'
    tablecreation='''create table tabletest (
                            rowid int,
                            tuplefield tuple < int, int, int >,
                            listfield list < int >,
                        primary key (rowid)
                    );'''

    # connect and create keyspace
    clu=Cluster([serverAddress])
    session=clu.connect()
    session.execute("create keyspace %s with replication = \
        {'class': 'SimpleStrategy', 'replication_factor': 1};" % keyspacename)

    # use keyspace; create a sample table
    session.set_keyspace(keyspacename)
    session.execute(tablecreation)

    # insert a row with rowid,listfield
    session.execute('insert into tabletest (rowid, listfield) values (%s,%s)', \
        [999, [10,11,12]])
    # succeeds

    # insert a row with rowid,tuplefield
    session.execute('insert into tabletest (rowid, tuplefield) values (%s,%s)', \
        [111, tuple([6,5,4])])
    # raises: *** InvalidRequest: Error from server: code=2200 [Invalid query]
    # message="Invalid list literal for tuplefield of type frozen<tuple<int, int, int>>"

    # Compare with analogous statements in cqlsh, which *both* succeed:
    # List:    insert into tabletest (rowid, listfield) values (999, [21,22,23]);
    # Tuple:   insert into tabletest (rowid, tuplefield) values (765, (121,122,123));

    # delete test keyspace
    session.execute("drop keyspace %s;" % keyspacename)    
    print "Test Finished."
“”
运行时使用:
python 2.7.10
cassandra驱动程序==3.7.1已安装
'''
从cassandra.cluster导入集群
如果“名称”=“\uuuuuuuu主要”:
serverAddress='SERVER\u地址'
keyspacename='tupletests'
tablecreation=''创建表tabletest(
rowid int,
tuplefield tuple,
列表字段列表,
主键(rowid)
);'''
#连接并创建键空间
clu=群集([serverAddress])
session=clu.connect()
session.execute(“使用复制创建密钥空间%s=\
{'class':'SimpleStrategy','replication_factor':1};%keyspacename)
#使用键空间;创建一个示例表
session.set_键空间(keyspacename)
session.execute(表创建)
#插入rowid为listfield的行
session.execute('insert into tabletest(rowid,listfield)值(%s,%s)'\
[999, [10,11,12]])
#成功
#插入一行,行ID为tuplefield
session.execute('insert into tabletest(rowid,tuplefield)值(%s,%s)'\
[111,元组([6,5,4]))
#引发:**InvalidRequest:来自服务器的错误:代码=2200[无效查询]
#message=“冻结类型的tuplefield的列表文字无效”
#与cqlsh中的类似语句比较,它们*都*成功:
#列表:在tabletest(rowid,listfield)中插入值(999、[21,22,23]);
#Tuple:插入tabletest(rowid,tuplefield)值(765,(121122123));
#删除测试键空间
执行(“删除键空间%s;%keyspacename”)
打印“测试完成”

好的,我刚刚解决了这个问题。在这里为大家发布解决方案。 为了让驱动程序在将元组传递给Cassandra时知道元组应如何格式化,如果坚持使用非准备语句进行插入,则必须在调用插入之前指定解析元组时使用的编码器:

session.encoder.mapping[tuple] = session.encoder.cql_encode_tuple
在这条语句之后,
Session.execute
insert语句中出现的元组将以正确的方式自动转换为Cassandra,Cassandra不再抱怨了

(据我所知,最好使用预先准备好的语句,其中包含足够的信息,不必单独指定编码器)