如何使用AWS Lambda从mysql数据库返回大量列?

2024-04-25 14:00:45 发布

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

简单的背景:我有一个连接到AWS RDS的无服务器mysql数据库,它由70列和7000多行组成。此RDS中定义的许多列的数据类型为VARCHAR(2000), BIGINT

我试图使用AWS Lambda api返回此数据库中的所有详细信息,下面是我用于实现相同目的的处理函数的代码片段:

def handler(event, context):
    try:

        #Storing data to be returned
        dataReturn=[]



        #Insert Data into Database
        with conn.cursor() as cur:
            cur.execute("SELECT <names of all 70 columns> FROM <table_name>" ) 
            row_headers=[x[0] for x in cur.description] #this will extract row headers
            rv = cur.fetchall()
            json_data=[]
            for result in rv:
                json_data.append(dict(zip(row_headers,result)))
            #print(json.dumps(json_data))
            conn.commit()



        return {
            'statusCode': 200,
            'headers': {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": 'GET, POST, PUT, DELETE, OPTIONS'
            },
            'body': json.dumps(json_data, cls=DecimalEncoder)
        }
    except Exception: 
        print(traceback.format_exc())
        return {
            'statusCode': 502,
            'headers': {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": 'GET, POST, PUT, DELETE, OPTIONS'
            },
            'body': json.dumps("Server Error Occured", cls=DecimalEncoder)
        }

但是,当我运行此命令时,会出现“502服务器错误”,其中包含以下日志:

Traceback (most recent call last):
  File "/var/task/getInstrumentsDetails.py", line 55, in handler
    print(json.dumps(json_data))
  File "/var/lang/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/var/lang/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/var/lang/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/var/lang/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Decimal is not JSON serializable

作为旁注,我可以使用以下命令从该表返回24列: SELECT <name_of_25_columns> FROM <table_name>,但是如果我试图显示超过24列,它将失败

这是否与AWS Lambda可以从RDS读取/返回的内存量有关? 请对此问题提出适当的解决方案

多谢各位


Tags: ofnameinpyjsondatareturnaccess
3条回答

我看不出上面对您的十进制编码的定义,但您应该能够使用以下简单的方法:

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            return float(obj)
        elif isinstance(obj, bytes):
            if len(obj) == 1:
                return ord(obj)
            else:
                return obj.decode()
        return json.JSONEncoder.default(self, obj)

请注意,如果要打印json.dumps的结果,还需要将自定义编码器传递到那里:print(json.dumps(json_data), cls=DecimalEncoder)

关于内存问题:Lambda可以使用128MB到3008MB,增量为64mb;拥有具有许多varchar列的7000+行会导致大量内存被使用;首先,通过在查询中使用LIMIT子句来确保代码是正确的,然后尝试对整个数据运行它

注意:您有一个不使用的dataReturn变量,还有一个conn.commit()语句,在读取(SELECTing)数据时不需要该语句

更新:根据新数据,您的问题似乎是byte数据而不是DecimalTypeError: Object of type bytes is not JSON serializable

例如,列Is_Record_Day_Wrkng是值为\x00的字节;如果这些字节值实际上应该是数字,您可以使用ord在JSON中对它们进行编码,但如果不是,您应该使用类似bytes.decode的内容-请参阅上面更新的编码

Lambda函数在默认情况下传输的数据量有一个上限,但您可以在aws控制台的API网关中更改它

我怀疑问题不在于列的数量,而是在24列之后,第25列是十进制类型——至少,这是错误消息实际报告的内容

您的返回函数指定了一个编码器,但您的print语句没有指定-它在上面的代码中被注释掉,但您显示的错误消息没有编码器:

Traceback (most recent call last):
  File "/var/task/getInstrumentsDetails.py", line 55, in handler
    print(json.dumps(json_data))

相关问题 更多 >