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

pyjq报错Cannot iterate over string,如何过滤boto3 IAM角色?

问题原因

报错「Cannot iterate over string」是因为你将page['Roles']序列化为JSON字符串后传给了pyjq.all(),但pyjq接受的是Python原生数据结构(列表/字典),而非序列化后的字符串。当pyjq尝试遍历字符串时,自然会抛出无法迭代字符串的错误。

解决步骤

1. 移除JSON序列化步骤

直接将page['Roles']这个Python列表传给pyjq,不需要用json.dumps()转换。

2. 处理Statement字段的两种格式

IAM角色的AssumeRolePolicyDocument中,Statement字段可能是单个字典或字典列表,需要统一处理成可迭代的列表,避免遍历出错。可以用[.] | flatten[]将单个对象转为列表后展开。

3. 筛选符合条件的角色

根据你的需求(筛选Principal为AWS的角色,排除Principal为service的角色),构造jq查询过滤掉包含service类型Principal的角色,再提取剩余角色中的AWS类型Principal。

修正后的代码
import pyjq
import boto3

client = boto3.client("iam")
paginator = client.get_paginator('list_roles')
response_iterator = paginator.paginate()

for page in response_iterator:
    # 直接使用Python原生列表,无需JSON序列化
    roles = page['Roles']
    
    # jq查询:过滤无service principal的角色,提取AWS principal
    filtered_principals = pyjq.all("""
        .[] 
        # 筛选所有Statement中都没有service类型Principal的角色
        | select(
            .AssumeRolePolicyDocument.Statement 
            | [.] | flatten[] 
            | all(.Principal.service | not)
        )
        # 处理Statement的单/列表格式,提取AWS principal
        | .AssumeRolePolicyDocument.Statement 
        | [.] | flatten[] 
        | .Principal.AWS
    """, roles)
    
    print(filtered_principals)
可选调整

如果你只是想提取所有包含AWS类型Principal的角色(即使该角色同时包含service类型Principal),可以修改jq查询为:

filtered_principals = pyjq.all("""
    .[] 
    | .AssumeRolePolicyDocument.Statement 
    | [.] | flatten[] 
    | select(.Principal.AWS) 
    | .Principal.AWS
""", roles)

内容的提问来源于stack exchange,提问作者prashanth pallu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:55:20