You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于boto3的DynamoDB查询在Python3.6正常,Python2.7出Tornado异常

问题分析与解决方案

核心问题拆解

从你的描述和报错信息来看,问题分两个关联部分:

  1. DynamoDB查询在Python2.7环境下未执行完成(查询后的打印语句无输出)
  2. 触发了Tornado WebSocket的AttributeError,根源是WebSocketClientConnection对象缺少log_exception方法

可能的原因

  • Boto3版本兼容性:Python2.7对新版本boto3的支持有限(boto3从1.14.0开始逐步放弃Python2.7支持),本地Py3.6使用的boto3版本可能和服务器Py2.7的版本不一致,导致查询语法或内部逻辑出错。
  • Tornado版本与Python2.7不兼容:报错里的log_exception方法在旧版本Tornado的WebSocketClientConnection中不存在,服务器上的Tornado版本可能过高(Tornado 6.0+放弃了Python2.7支持),导致和Py2.7环境冲突。
  • 查询语法的隐式错误:Python2.7和3.x在运算符优先级上有细微差异,看似正确的查询条件可能在Py2.7下触发boto3内部未捕获异常,进而导致Tornado的WebSocket回调崩溃。

分步解决方案

1. 锁定兼容Python2.7的Boto3版本

首先检查服务器上的boto3版本:

pip2 show boto3

Python2.7支持的最后几个稳定boto3版本是1.13.x系列,若服务器版本高于此范围,降级到兼容版本:

pip2 install boto3==1.13.28 botocore==1.16.28

(注:botocore是boto3的核心依赖,必须匹配对应版本)

2. 修复DynamoDB查询的语法兼容性

Python2.7中&运算符的优先级可能引发隐式错误,建议显式用括号包裹条件,或使用boto3官方的And方法:

# 方式1:显式括号包裹条件
KeyConditionExpression = (Key('OTP').eq(otp)) & (Key('SNo').between(1,5))

# 方式2:使用boto3的And方法(更具兼容性)
from boto3.dynamodb.conditions import And
KeyConditionExpression = And(Key('OTP').eq(otp), Key('SNo').between(1,5))

3. 修复Tornado WebSocket的log_exception错误

这个错误是Tornado版本过高导致的,解决方法二选一:

  • 降级Tornado到兼容版本:安装支持Python2.7的最高稳定版本
pip2 install tornado==5.1.1
  • 临时补丁(不推荐长期使用):手动给WebSocketClientConnection添加缺失的方法,放在Tornado初始化代码之前:
from tornado.websocket import WebSocketClientConnection
import logging

def patch_log_exception(self, *args, **kwargs):
    logging.error("WebSocket exception occurred:", exc_info=args)

WebSocketClientConnection.log_exception = patch_log_exception

4. 添加异常捕获,排查真实错误

当前异常被Tornado回调逻辑掩盖,建议给DynamoDB查询添加try-except块,捕获并打印真实错误:

try:
    response = table.query(
        IndexName = "XXX-XXX-index",
        ProjectionExpression = "AssessID,SNo,Details,Status,OTP",
        KeyConditionExpression = (Key('OTP').eq(otp)) & (Key('SNo').between(1,5))
    )
    print ("response code is executing file")
    print("Query response:", response)
except Exception as e:
    print("DynamoDB query error:", str(e))
    import traceback
    traceback.print_exc()

这样可以直接看到DynamoDB查询是否抛出异常,而不是被WebSocket错误掩盖。


验证步骤

  1. 先降级boto3和Tornado到兼容版本
  2. 修改查询语法为兼容Py2.7的形式
  3. 添加异常捕获代码,运行后查看错误输出
  4. 测试查询是否正常执行,打印出response内容

内容的提问来源于stack exchange,提问作者r Reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:54:38