Python3与Cassandra使用UDT插入数据时遇KeyError:0求助
Cassandra UDT插入时KeyError:0的解决办法
问题分析与修复步骤
1. INSERT语句列顺序与表定义不匹配
你的INSERT语句中displayname和username的顺序和表定义的列顺序颠倒了:
- INSERT列顺序:
id, displayname, username, email... - 表定义列顺序:
id, username, displayname, email...
这会导致参数绑定错位,驱动解析时出现错误。
修复后的INSERT语句:
query = "INSERT INTO accounts (id, username, displayname, email, joined, status, password, bio, pinnedupdate, interest, notice, details, connection, purge) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
2. UDT字段顺序与Cassandra定义不一致
Cassandra的UDT是位置敏感的,驱动会按字段定义的顺序解析值,与Python字典的键名顺序无关:
account_interest定义顺序:topics, fields, tags- 你传入的字典顺序:
fields, tags, topics
字段值错位会导致驱动无法正确匹配,引发KeyError。同理其他UDT的字段顺序也需与定义完全一致。
修复后的interest参数:
{ 'topics': [], 'fields': [], 'tags': [] }
修复后的notice参数:
{ 'code': 0, 'updatelock': False, 'updatephotolock': False, 'updatevideolock': False, 'customproflock': False, 'dmlock': False, 'suspended': False, 'suspendreason': '', 'acknowledged': True }
修复后的details参数:
{ 'verified': False, 'private': False, 'website': '', 'emailapproved': False, 'pronouns': '', 'labels': [], 'likesprivate': False }
3. 数据类型不匹配
email字段在表中是set<text>,你传入的是列表[req['email']],需改为集合{req['email']}connection字段是set<FROZEN<connection>>,你传入的是空列表[],需改为空集合set()
4. 时间戳类型优化
purge里的schedule字段是timestamp类型,建议直接传入datetime对象,驱动会自动处理格式,避免手动转换可能出现的问题:
schedule=datetime.now()
修复后的完整参数示例
insert_var = ( userid, limit_string_length(username_string(req['username']), 20), # 对应表的username列 limit_string_length(req['username'], 20), # 对应表的displayname列 {req['email']}, # 改为set类型 int(datetime.now().timestamp())*1000, 'public', str(bcrypt.hashpw(password_bytes, bcrypt.gensalt(12)).decode('utf-8')), '', None, { 'topics': [], 'fields': [], 'tags': [] }, { 'code': 0, 'updatelock': False, 'updatephotolock': False, 'updatevideolock': False, 'customproflock': False, 'dmlock': False, 'suspended': False, 'suspendreason': '', 'acknowledged': True }, { 'verified': False, 'private': False, 'website': '', 'emailapproved': False, 'pronouns': '', 'labels': [], 'likesprivate': False }, set(), # 改为空set { 'status': 'public', 'reason': '', 'schedule': datetime.now() } )
内容的提问来源于stack exchange,提问作者aliamanuba
相关产品推荐
相关产品推荐

