Amazon RDS实例的Python解析字典输出问题

2024-09-26 22:49:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python解析来自AWS的boto接口的dict输出,它应该能为我提供所有AmazonRDS(数据库)实例的信息。我对这里使用的所有工具都是新手,所以请原谅我的无知

我试图把它当作一个数组来对待,这可能是一个不好的前提,因为它是dict类型。下面的代码可以很好地拉取两(2)个实例,这很奇怪-它至少可以重复一次,我已经通过打印dict输出验证了我在该区域运行的所有四(4)个实例-但它不会拉取输出中的后两个。当我使用len()来测量输出的长度时,它返回2

有人能帮我理解我需要对这段代码做什么才能让它真正解析出所有返回的实例吗?(然后,功能是查找重新启动的允许标记,如果为1,则停止实例…这似乎工作正常,但同样,仅针对返回的前两个结果。)

import json
import boto3

region = 'us-east-1'
rds = boto3.client('rds')

def lambda_handler(event, context):
    # Ingest all RDS instances
    dbinstances = rds.describe_db_instances() # Filtering by instance status is not supported
    
    print('* * *')
    
    # Set db instance counter for below loop   
    dbi = 0

    # Loop through each running RDS instance, checking tags and shutting down if tags match
    for dbinstance in dbinstances:
        # Set default values for tags we'll parse
        rebootAllowed = 0
        # We'll need this later
        try:
            dbinstanceId = dbinstances.get('DBInstances')[dbi]['DBInstanceIdentifier']
            dbinstanceArn = dbinstances.get('DBInstances')[dbi]['DBInstanceArn']
            rdstags = rds.list_tags_for_resource(ResourceName=dbinstanceArn)
            # Attempt to look into tags for EC2s that have them. If they don't, we'll get an exception
            try:
                # Does the instance have the rebootAllowed tag? Great, what's its value?
                if 'rebootAllowed' in rdstags['TagList'][dbi]['Key']:
                    rebootAllowed = rdstags['TagList'][dbi]['Value']
                # Let's log what we're doing.
                print('Examining RDS instance ' + dbinstanceId + '...')
                # Attempt to stop instance
                try:
                    if rebootAllowed == '1':
                        message = '-- This instance CAN be stopped. Doing that now.'
                        rdsid = [dbinstanceId]
                        rds.stop_db_instance(DBInstanceIdentifier=dbinstanceId)
                    elif rebootAllowed == '0':
                        message = '-- This instance is BLOCKED from being stopped. Doing nothing.'
                    else:
                        message = '-- This instance does not have the tags used by this script. Skipping.'
                except Exception, err:
                    message = 'Error with RDS instance: instanceId: ' +  err
                    raise err
                print (message)
                print ('* * *')
                dbi += 1
            except:
                print('Examining RDS instance ' + dbinstanceId + ')')
                print('-- An EXECPTION occurred while analyzing this instance. This could be because the instance has no tags at all.')
                print('* * *')
                dbi += 1
        except:
            print('End of list. Script complete.')

Tags: the实例instancemessagefortagsthisdict
1条回答
网友
1楼 · 发布于 2024-09-26 22:49:31

要确切地说出发生了什么有点困难,特别是因为我们不知道您试图迭代的dict的形状是什么,但看起来您确实感觉到了潜在的问题:您并没有真正以pythonical方式处理此迭代

我查找了输出,发现了以下示例:

{
    "DBInstances": [
        {
            "DBInstanceIdentifier": "mydbinstancecf",
            "DBInstanceClass": "db.t3.small",
            "Engine": "mysql",
            "DBInstanceStatus": "available",
            "MasterUsername": "masterawsuser",
            "Endpoint": {
                "Address": "mydbinstancecf.abcexample.us-east-1.rds.amazonaws.com",
                "Port": 3306,
                "HostedZoneId": "Z2R2ITUGPM61AM"
            },
            ...some output truncated...
        }
    ]
}

因此,您可以通过在dbinstances中删除无关数据来简化循环

# dbinstances = rds.describe_db_instances() becomes
dbinstances = rds.describe_db_instances()["DBInstances"]

现在,您正在处理一组db实例。在PythonFor循环中,将iterarable(list)的每个元素作为变量。在这种情况下,根本不需要维护dbi计数器。如果您确实想要计算元素,您可以这样做for i, e in enumerate(my_list):,其中i是索引,e是元素

因此,您的循环变得更像这样:

for instance in dbinstances: 
# Set default values for tags we'll parse
    rebootAllowed = 0
    # We'll need this later
    try:
       dbinstanceId = instance['DBInstanceIdentifier']
       dbinstanceArn = instance['DBInstanceArn']
       rdstags = rds.list_tags_for_resource(ResourceName=dbinstanceArn)
#     ... the rest is left as an exercise for Josh

一般来说,在用Python设计这种算法时,应该大量使用REPL。您可以四处探索并尝试,以快速了解数据的实际结构

相关问题 更多 >

    热门问题