使用Python将大尺寸的压缩JSON文件从AmazonS3导入AWS RDS PostgreSQL

使用Python将大尺寸的压缩JSON文件从AmazonS3导入AWS RDS PostgreSQL,python,postgresql,amazon-s3,etl,amazon-rds,Python,Postgresql,Amazon S3,Etl,Amazon Rds,我正在尝试使用Python将一个大尺寸的压缩JSON文件从AmazonS3导入AWS RDS PostgreSQL。但是,这些错误发生了 回溯(最近一次呼叫最后一次): 文件“my_code.py”,第64行,在 file_content=f.read().decode('utf-8').splitlines(真) 文件“/usr/lib64/python3.6/zipfile.py”,第835行,已读 buf+=self.\u read1(self.MAX\u N) 文件“/usr/lib64

我正在尝试使用Python将一个大尺寸的压缩JSON文件从AmazonS3导入AWS RDS PostgreSQL。但是,这些错误发生了

回溯(最近一次呼叫最后一次):

文件“my_code.py”,第64行,在 file_content=f.read().decode('utf-8').splitlines(真)

文件“/usr/lib64/python3.6/zipfile.py”,第835行,已读 buf+=self.\u read1(self.MAX\u N)

文件“/usr/lib64/python3.6/zipfile.py”,第925行,在_read1中 数据=自身。解压器。解压(数据,n)

记忆者

//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()
导入系统 进口boto3 导入psycopg2 进口拉链 输入io 导入json 导入配置 s3=boto3.client('s3',aws\U access\U key\U id=,aws\U secret\U access\U key=) connection=psycopg2.connect(主机=,数据库名=,用户=,密码=) cursor=connection.cursor() bucket=sys.argv[1] key=sys.argv[2] obj=s3.get_对象(Bucket=Bucket,Key=Key) def insert_query(): query=”“” 插入到数据表中 挑选 (src.test->>'url')::varchar,(src.test->>'id')::bigint, (src.test->>'external_id')::bigint,(src.test->>'via')::jsonb 从(选择强制转换(%s作为JSONB)作为测试)src """ execute(查询,(json.dumps(数据),) 如果key.endswith('.zip'): zip_files=obj['Body'].read() 使用io.BytesIO(zip_文件)作为zf: zf.seek(0) 将zipfile.zipfile(zf,mode='r')作为z: 对于z.namelist()中的文件名: 将z.open(文件名)作为f: file_content=f.read().decode('utf-8').splitlines(真) 对于文件内容中的行: data=json.loads(行) 插入查询() 如果key.endswith('.json'): file_content=obj['Body'].read().decode('utf-8').splitlines(True) 对于文件内容中的行: data=json.loads(行) 插入查询() commit()连接 连接。关闭()
这些问题有什么解决办法吗?任何帮助都可以,非常感谢

问题是您试图一次将整个文件读入内存,如果文件确实太大,可能会导致内存不足

您应该一次读取一行文件,因为文件中的每一行显然都是JSON字符串,所以您可以直接在循环中处理每一行:

with z.open(filename) as f:
    for line in f:
        insert_query(json.loads(line.decode('utf-8')))
您的
insert\u查询
函数应该接受
数据
作为参数,顺便说一下:

def insert_query(data):

请发布完整堆栈的traceTraceback(最后一次调用):文件“my_code.py”,第64行,在文件“content=f.read().decode('utf-8')。拆分行(True)文件“/usr/lib64/python3.6/zipfile.py”,第835行,在read buf+=self.\u read1(self.MAX\N)文件“/usr/lib64/python3.6/zipfile.py”,第925行,在_read1data=self._decompressor.decompressor(data,n)memoryerror中解压到问题回溯中(最后一次调用):文件“my_code.py”,第26行,在data=json.loads(json.loads(line.decode('utf-8'))文件/usr/lib64/python3.6/json/u init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.py),第348行,加载“not)TypeError:JSON对象必须是str、bytes或bytearray,而不是“dict”,您不必要地调用
JSON.loads
两次,方法是将
JSON.loads的返回值传递给
JSON.loads
。请改用我的代码。