postgresql 亚马逊极光postgres无服务器:数据库返回的值超过允许的响应大小限制

kcrjzv8t  于 2023-03-12  发布在  PostgreSQL
关注(0)|答案(4)|浏览(171)

我们正在为我们的一个项目探索Aurora无服务器作为数据库存储。当执行POC以从Aurora无服务器集群获取事件时,我们收到“数据库返回超过允许的响应大小限制”异常。
1.是否有一个内置的解决方案?是否有一个令牌机制类似于极光无服务器中的dynamoDB?
1.快速获取50,000是我们的关键要求之一。我们应该使用极光还是极光无服务器?
有关数据库的详细信息:Aurora PostgreSQL服务器更少。
对于POC,我们使用的是数据API,它有以下限制。

import boto3;

client = boto3.client('rds-data')

import sys;
sql_statement = "select * from table_name limit 1000"

response = client.execute_statement(  
    database='mydb',  
    secretArn='<secret_arn',  
    resourceArn='<resource_arn>',  
    sql=sql_statement  
) 

print(response);
thigvfpy

thigvfpy1#

当您通过Data API在任何Aurora无服务器示例中执行查询时,有两个大小限制:
1.返回的每行不能大于64 KB;(资料来源)
1.结果集不能大于1 MB。(源代码)
目前,Data API中还没有解决方案来克服这些限制。在Amazon Aurora User Guide中,第164页中有针对第二个问题的推荐解决方案:
在这种情况下,数据库返回的结果集太大。数据库返回的结果集中的Data API限制为1 MB。若要解决此问题,请确保对Data API的调用返回1 MB或更少的数据。如果需要返回大于1 MB的数据,可以在查询中使用带有LIMIT子句的多个ExecuteStatement调用。
考虑到这一点,您可以执行指数回退,直到为结果集找到一个可接受的LIMIT,或者设置一个固定的LIMIT,使其始终低于1 MB,即使将来行大小增加也是如此。
定义如何设置LIMIT子句值(取决于集群使用MySQL 5.6MySQL 5.7还是PostgreSQL 10.7)后,您可以执行COUNT查询以了解将获得多少结果,然后迭代直到执行COUNT / LIMIT语句。另一个选项是迭代直到语句响应的行数少于LIMIT。

xdnvmnnf

xdnvmnnf2#

由于某些原因,panda read_sql的“chunksize”参数在AWS Data API中不能很好地运行。顺便说一句,我使用的是MySQL,但pydataapi应该支持两者。
我发现这个问题的解决方案是使用Pandas的read_sql和字符串格式的LIMIT迭代查询数据库。
我首先使用以下语法得到表的长度

df_status = pd.read_sql('show table status like "yourtable";', con = sql_engine)

然后使用numpy.arange()来确定请求的起始行。每个查询都将请求由“chunksize”参数指定的行数。我选择了20,000,但您应该选择不会导致响应大于1MB的最大值。
接下来就是连接 Dataframe 列表的问题了,我发现这是目前最优的解决方案。

import pandas as pd
    import numpy as np
    import boto3
    from sqlalchemy import create_engine

    cluster_arn = 'yourcluster'
    secret_arn = 'yoursecret'
    database = 'mydb'
    chunksize = 20000

    rdsData = boto3.client('rds-data', region_name = 'yourregion')
    sql_engine = create_engine('mysql+pydataapi://',
                               connect_args = {
                                   'resource_arn': cluster_arn,
                                   'secret_arn': secret_arn,
                                   'database': database,
                                   'client': rdsData}).connect()
    df_status = pd.read_sql("show table status like 'yourtable';", con = sql_engine)
    rownum = df_status.loc[0, "Rows"]
    space = np.arange(0, rownum, chunksize)
    space = space.tolist()
    space.append(rownum)
    df_list = []
    for i in space:
        df = pd.read_sql("select * from yourtable LIMIT {}, {}".format(i, chunksize), con = sql_engine)
        df_list.append(df)
    big_df = pd.concat(df_list)
    sql_engine.close()
qgelzfjb

qgelzfjb3#

https://github.com/cloud-utils/aurora-data-api处理此问题
使用库获取所有查询的快速示例

with aurora_data_api.connect(aurora_cluster_arn=cluster_arn, secret_arn=secret_arn, database="cool_db_name_here") as conn:
    with conn.cursor() as cursor:
        cursor.execute("select * from cool_table")
        data = cursor.fetchall()
7eumitmz

7eumitmz4#

我想分享另一个jameshgrn提到的使用panda的read_sql的例子。我试图使它更短,更易读。它还通过计算行数而不是使用表状态命令来允许查询的灵活性。但是,如果表有大量的行,这种方法可能会更慢,因为它需要一个count(*)查询。

chunksize = 10000
with engine.connect() as conn:
    result = conn.execute("select count(*) from your_tbl").fetchone()
    row_num = result[0]
    chunks = [
        pd.read_sql("select * from your_tbl limit {} offset {}".format(chunksize, i), con = conn)
        for i in range(0, row_num, chunksize)
    ]
    data_df = pd.concat(chunks, ignore_index=True)

相关问题