Skip to content

输入输出处理

BodoSQL非常适合基于计算的SQL查询,但目前你无法直接通过SQL访问外部存储。相反,你可以使用Bodo和各种Python API加载和存储数据。在这里,我们解释了几种常用的数据加载方法。

Pandas IO 在 JIT 函数中的 SQL 查询

加载数据最常见的方法是首先使用Pandas API在JIT函数内加载一个DataFrame,然后在BodoSQLContext中使用该DataFrame。

def f(f1, f2):
    df1 = pd.read_parquet(f1)
    df2 = pd.read_parquet(f2)
    bc = bodosql.BodoSQLContext(
        {
            "T1": df1,
            "T2": df2,
        }
    )
    return bc.sql("select t1.A, t2.B from t1, t2 where t1.C > 5 and t1.D = t2.D")

Pandas IO在与查询分开的JIT函数中

之前的方法对于大多数单个查询效果很好。然而,当在同一数据集上运行多个查询时,理想情况下应该只加载一次以供所有查询使用。为此,您可以将您的JIT代码结构化为在开头包含一个单独的加载函数。例如:

@bodo.jit
def load_data(f1, f2):
    df1 = pd.read_parquet(f1)
    df2 = pd.read_parquet(f2)
    return df1, df2

def q1(df1, df2):
    bc = bodosql.BodoSQLContext(
        {
            "T1": df1,
            "T2": df2,
        }
    )
    return bc.sql("select t1.A, t2.B from t1, t2 where t1.C > 5 and t1.D = t2.D")

...

@bodo.jit
def run_queries(f1, f2):
    df1, df2 = load_data(f1, f2)
    print(q1(df1, df2))
    print(q2(df2))
    print(q3(df1))
    ...

run_queries(f1, f2)

这种方法会阻止某些优化,例如过滤下推。然而,这里的假设是您将在各种基准测试中使用整个 DataFrame,因此单独的优化是没有用的。此外,任何可以应用于所有查询的优化都可以在 load_data 中明确进行。例如,如果所有查询都在单一天的数据上使用 df1,您可以在 load_data 中写入该过滤器以限制 IO,并会执行过滤下推。

@bodo.jit
def load_data(f1, f2, target_date):
    df1 = pd.read_parquet(f1)
    # Applying this filter limits how much data is loaded.
    df1 = df1[df1.date_val == target_date]
    df2 = pd.read_parquet(f2)
    return df1, df2

@bodo.jit
def run_queries(f1, f2, target_date):
    df1, df2 = load_data(f1, f2, target_date)
    ...

run_queries(f1, f2, target_date)