Как вернуть большое количество столбцов из базы данных mysql, используя AWS Lambda? - PullRequest
0 голосов
/ 13 марта 2020

Краткая справка: у меня есть безсерверная база данных mysql, подключенная к AWS RDS, которая состоит из 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

Как sidenote, я могу вернуть 24 столбца из этой таблицы, используя: SELECT <name_of_25_columns> FROM <table_name>, но произойдет сбой, если я попытаюсь отобразить более 24 столбцов.

Эта проблема связана с объемом памяти, который AWS Лямбда может читать / возвращать из RDS? Пожалуйста, предложите подходящее решение этой проблемы.

Спасибо

Ответы [ 3 ]

1 голос
/ 14 марта 2020

У лямбда-функций есть ограничение на количество данных, которые они будут передавать по умолчанию, но вы можете изменить это в шлюзе API в вашей консоли aws.

1 голос
/ 13 марта 2020

Я подозреваю, что проблема не в количестве столбцов, а в том, что после 24 столбцов ваш 25-й столбец имеет десятичный тип - по крайней мере, именно об этом сообщает сообщение об ошибке.

Ваша функция возврата задает кодировщик, но ваш оператор печати - нет. Он закомментирован в коде выше, но в отображаемом сообщении об ошибке нет кодировщика:

Traceback (most recent call last):
  File "/var/task/getInstrumentsDetails.py", line 55, in handler
    print(json.dumps(json_data))
0 голосов
/ 13 марта 2020

Я не вижу определения вашего DecimalEncoder выше, но вы должны иметь возможность использовать что-то простое:

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 может использовать 128 МБ до 3008 МБ с шагом 64 МБ; наличие 7000 + строк со многими столбцами varchar может привести к значительному использованию памяти; сначала убедитесь, что ваш код правильный, используя в запросе предложение LIMIT, а затем попробуйте запустить его для всех данных.

Примечание: у вас есть переменная dataReturn, которую вы не используете, и вы иметь оператор conn.commit(), который не требуется при чтении ( SELECT ing) данных.

Обновление : на основе новых данных кажется, что ваша проблема с byte данными, а не Decimal: TypeError: Object of type bytes is not JSON serializable

Например, столбец Is_Record_Day_Wrkng это байт со значением \x00; если эти байтовые значения на самом деле должны быть числами, вы можете использовать ord для кодирования их в JSON, но если нет, вы должны использовать что-то вроде bytes.decode - см. обновленное кодирование выше.

...