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

使用Boto3的transact_write_items时触发__enter__错误求助

问题原因与解决方法:DynamoDB transact_write_items 报__enter__错误

问题描述

编写Python代码调用Boto3的transact_write_items接口向DynamoDB写入数据,执行时控制台打印HERE: __enter__错误,但DynamoDB表已成功新增条目。测试环境为Windows,通过SAM CLI执行命令:

npx cdk ls; sam local invoke ReportManager-Lambda -t ./cdk.out/GlobalStack.template.json -e .\events\create_report.json

原代码如下:

def create_report_and_update_user(db_client, report_info):
    # TODO:: This will correctly perform operations, but will return a __enter__ error. Figure out why...
    report_info = json.loads(json.dumps(report_info), parse_float=Decimal)
    user_email = report_info["email"]
    report_id = (
        "R-" + str(uuid.uuid4())
        if not report_info.get("report_id")
        else report_info.get("report_id")
    )

    report_data = {
        "report_id": report_id,
        "creation_date": str(datetime.now()),
        "email": user_email,
        "loan_details": report_info["loan_details"],
        "purchase_details": report_info["purchase_details"],
        "property_details": report_info["property_details"],
        "monthly_budget": report_info["monthly_budget"],
    }

    serializer = TypeSerializer()
    report_data = {
        key: serializer.serialize(value) for key, value in report_data.items()
    }
    try:
        print("open is assigned to %r" % open)
        with db_client.transact_write_items(
            TransactItems=[
                {
                    "Put": {
                        "TableName": REPORTS_TABLE_NAME,
                        "Item": report_data,
                        "ConditionExpression": "attribute_not_exists(report_id)",
                    }
                },
            ]
        ) as response:
            print("Inside transact_write_items")
            return response
    except Exception as e:
        print("HERE: ", e)

错误原因

Boto3的transact_write_items是普通同步API调用方法,不支持上下文管理器(with语句)。强行使用with时,Python会尝试调用该方法返回对象的__enter__方法,但该方法不存在,因此抛出__enter__错误。

数据能成功写入是因为transact_write_items本身已经执行完成,错误是后续上下文管理器触发的,不影响之前的写入操作。你排查的open函数未被覆盖和此错误无关。

解决方法

去掉with语句,直接调用方法并获取响应即可,修改后的代码如下:

def create_report_and_update_user(db_client, report_info):
    # TODO:: This will correctly perform operations, but will return a __enter__ error. Figure out why...
    report_info = json.loads(json.dumps(report_info), parse_float=Decimal)
    user_email = report_info["email"]
    report_id = (
        "R-" + str(uuid.uuid4())
        if not report_info.get("report_id")
        else report_info.get("report_id")
    )

    report_data = {
        "report_id": report_id,
        "creation_date": str(datetime.now()),
        "email": user_email,
        "loan_details": report_info["loan_details"],
        "purchase_details": report_info["purchase_details"],
        "property_details": report_info["property_details"],
        "monthly_budget": report_info["monthly_budget"],
    }

    serializer = TypeSerializer()
    report_data = {
        key: serializer.serialize(value) for key, value in report_data.items()
    }
    try:
        print("open is assigned to %r" % open)
        # 移除with语句,直接调用API
        response = db_client.transact_write_items(
            TransactItems=[
                {
                    "Put": {
                        "TableName": REPORTS_TABLE_NAME,
                        "Item": report_data,
                        "ConditionExpression": "attribute_not_exists(report_id)",
                    }
                },
            ]
        )
        print("Inside transact_write_items")
        return response
    except Exception as e:
        print("HERE: ", e)

补充说明

Boto3中仅部分涉及资源管理的操作(如特定流操作、客户端专属上下文方法)支持with语句,绝大多数普通API调用都是直接执行并返回结果,无需使用上下文管理器。

内容的提问来源于stack exchange,提问作者Qwerty Qwerts

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:37:33