You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在代码中覆盖Kedro数据集查询的WHERE子句?

动态修改Kedro GBQQueryDataset的WHERE子句参数

问题场景

现有Kedro目录配置如下:

some_table.raw:
    type: pandas.GBQQueryDataset
    sql: SELECT * FROM database.table WHERE date >= {start_date}

需要在代码中动态传递start_date参数,期望调用方式类似:

catalog.load("some_table.raw", query={"start_date": "2024-01-01"})

但catalog.load不支持额外参数,且TemplatedConfigLoader只能绑定单一固定值,无法满足代码不同部分传递不同参数的需求。

三种可行解决方案

1. 自定义数据集类

继承GBQQueryDataset,扩展支持动态参数注入:

from kedro_datasets.pandas import GBQQueryDataset

class DynamicGBQQueryDataset(GBQQueryDataset):
    def __init__(self, sql: str, **kwargs):
        self.base_sql = sql
        super().__init__(sql=sql, **kwargs)
    
    def load(self, **query_params):
        # 渲染带参数的SQL语句
        self.sql = self.base_sql.format(**query_params)
        return super().load()

更新目录配置使用自定义数据集:

some_table.raw:
    type: your.module.path.DynamicGBQQueryDataset
    sql: SELECT * FROM database.table WHERE date >= {start_date}
    # 补充GBQ必填参数,如project_id、credentials等

代码中调用:

data = catalog.load("some_table.raw").load(start_date="2024-01-01")

2. 利用Kedro钩子动态修改配置

通过before_dataset_created钩子,在数据集实例化前替换SQL参数:

from kedro.framework.hooks import hook_impl
from kedro_datasets.pandas import GBQQueryDataset

class DynamicQueryHook:
    # 用类属性临时存储参数,避免全局变量污染
    _query_params = {}

    @classmethod
    def set_params(cls, **params):
        cls._query_params = params

    @hook_impl
    def before_dataset_created(self, dataset_name: str, dataset_config: dict):
        if dataset_name == "some_table.raw" and dataset_config["type"] == "pandas.GBQQueryDataset":
            if self._query_params:
                dataset_config["sql"] = dataset_config["sql"].format(**self._query_params)
                self._query_params = {}  # 重置参数,避免影响后续加载

在settings.py中注册钩子:

HOOKS = [DynamicQueryHook()]

代码中调用:

DynamicQueryHook.set_params(start_date="2024-01-01")
data = catalog.load("some_table.raw")

3. 编写数据集加载工厂函数

直接从配置中读取模板SQL,渲染后创建数据集实例:

from kedro.io import DataCatalog
from kedro_datasets.pandas import GBQQueryDataset

def load_gbq_with_params(catalog: DataCatalog, dataset_name: str, **query_params):
    # 获取原始数据集配置
    catalog_config = catalog._config_loader.get("catalog")[dataset_name]
    # 渲染SQL模板
    rendered_sql = catalog_config["sql"].format(**query_params)
    # 构建并返回加载后的数据
    dataset = GBQQueryDataset(
        sql=rendered_sql,
        **{k: v for k, v in catalog_config.items() if k not in ["type", "sql"]}
    )
    return dataset.load()

代码中调用:

data = load_gbq_with_params(catalog, "some_table.raw", start_date="2024-01-01")

内容的提问来源于stack exchange,提问作者Ivan Konovalov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:20:29