Импорт большого размера сжатого файла JSON из Amazon S3 в AWS RDS-PostgreSQL с использованием Python

1

Я пытаюсь импортировать большой размер ZIPPED JSON FILE из Amazon S3 в AWS RDS-PostgreSQL с использованием Python. Но эти ошибки возникли,

Traceback (последний последний вызов):

Файл "my_code.py", строка 64, в файле_content = f.read(). Decode ('utf-8'). Splitlines (True)

Файл "/usr/lib64/python3.6/zipfile.py", строка 835, в read buf + = self._read1 (self.MAX_N)

Файл "/usr/lib64/python3.6/zipfile.py", строка 925, в _read1 data = self._decompressor.decompress (данные, n)

MemoryError

//my_code.py

import sys
import boto3
import psycopg2
import zipfile
import io
import json
import config

s3 = boto3.client('s3', aws_access_key_id=<aws_access_key_id>, aws_secret_access_key=<aws_secret_access_key>)
connection = psycopg2.connect(host=<host>, dbname=<dbname>, user=<user>, password=<password>)
cursor = connection.cursor()

bucket = sys.argv[1]
key = sys.argv[2]
obj = s3.get_object(Bucket=bucket, Key=key)


def insert_query():
    query = """
        INSERT INTO data_table
        SELECT
            (src.test->>'url')::varchar, (src.test->>'id')::bigint,
            (src.test->>'external_id')::bigint, (src.test->>'via')::jsonb
        FROM (SELECT CAST(%s AS JSONB) AS test) src
    """
    cursor.execute(query, (json.dumps(data),))


if key.endswith('.zip'):
    zip_files = obj['Body'].read()
    with io.BytesIO(zip_files) as zf:
        zf.seek(0)
        with zipfile.ZipFile(zf, mode='r') as z:
            for filename in z.namelist():
                with z.open(filename) as f:
                    file_content = f.read().decode('utf-8').splitlines(True)
                    for row in file_content:
                        data = json.loads(row)
                        insert_query()
if key.endswith('.json'):
    file_content = obj['Body'].read().decode('utf-8').splitlines(True)
    for row in file_content:
        data = json.loads(row)
        insert_query()

connection.commit()
connection.close()

Есть ли какие-либо решения этих проблем? Любая помощь сделана, спасибо вам большое!

  • 0
    пожалуйста выложите полную трассировку стека
  • 0
    Traceback (последний вызов был последним): файл "my_code.py", строка 64, в файле <module> file_content = f.read (). Decode ('utf-8'). Splitlines (True) "/ usr / lib64 / python3.6 / zipfile.py ", строка 835, в файле read buf + = self._read1 (self.MAX_N)" /usr/lib64/python3.6/zipfile.py ", строка 925, в _read1 data = self. _decompressor.decompress (data, n) MemoryError
Показать ещё 1 комментарий
Теги:
amazon-s3
etl
amazon-rds

1 ответ

1
Лучший ответ

Проблема в том, что вы пытаетесь одновременно считывать весь файл в память, что может привести к тому, что у вас закончится нехватка памяти, если файл действительно слишком большой.

Вы должны прочитать файл по одной строке за раз, и поскольку каждая строка в файле, по-видимому, является строкой JSON, вы можете обрабатывать каждую строку непосредственно в цикле:

with z.open(filename) as f:
    for line in f:
        insert_query(json.loads(line.decode('utf-8')))

Функция insert_query должна принимать data как параметр, кстати:

def insert_query(data):
  • 0
    Traceback (последний вызов был последним): файл "my_code.py", строка 26, в файле <module> data = json.loads (файл json.loads (line.decode ('utf-8'))) "/ usr / lib64 /python3.6/json/__init__.py ", строка 348, в загрузках 'not {! r}'. format (s .__ class __.__ name__)) TypeError: объект JSON должен быть str, bytes или bytearray, а не 'dict '
  • 0
    Вы без необходимости вызываете json.loads дважды, передавая возвращаемое значение json.loads в json.loads . Пожалуйста, используйте мой код вместо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню