python - 如何将 config.py 中的 Python 参数传递给 .sql 文件?

我正在使用 Python Snowflake 连接器从 Snowflake 中的表中提取数据。这是我的文件结构:

sql
   a.sql
   b.sql
   c.sql
configurations.py
data_extract.py
main.py

这里的 sql 文件夹包含我在 .sql 文件中的所有 sql 查询。我将这些 sql 文件分开放置,因为它们都是一串串长长的行,如果我将它们放入 python 文件中,它们看起来很乱。 configuration.py 包含我想在每次运行代码时更改的日期时间参数。它看起来像这样:

START_TIME = '2018-10-01 00:00:00'
END_TIME = '2019-04-01 00:00:00'

我想将这些参数添加到 .sql 文件中。例如,a.sql 包含以下内容:

DECLARE
  @START_PICKUP_DATE DATE,
  @END_PICKUP_DATE DATE,

SET
  @START_PICKUP_DATE = '2018-10-01'

SET
  @END_PICKUP_DATE = '2019-04-01'

select supplier_confirmation_id, pickup_datetime, dropoff_datetime, pickup_station_distance
from SANDBOX.ZQIAN.V_PDL
where pickup_datetime >= START_PICKUP_DATE and pickup_datetime < END_PICKUP_DATE
      and supplier_confirmation_id is not null;

我通过以下方式在我的 python 代码中使用 a.sql:

def executeSQLScriptsFromFile(filepath):
    # snowflake credentials, replace SECRET with your own
    ctx = snowflake.connector.connect(
        user='S_ANALYTICS_USER',
        account=SECRET_A,
        region='us-east-1',
        warehouse=SECRET_B,
        database=SECRET_C,
        role=SECRET_D,
        password=SECRET_E)

    fd = open(filepath, 'r')
    query = fd.read()
    fd.close()

    cs = ctx.cursor()
    try:
        cur = cs.execute(query)
        df = pd.DataFrame.from_records(iter(cur), columns=[x[0] for x in cur.description])
    finally:
        cs.close()
    ctx.close()

    return df

def extract_data():
    a_sqlpath = os.path.join(os.getcwd(), 'sql\a.sql')
    a_df = executeSQLScriptsFromFile(a_sqlpath)
    return a_df

问题是我希望同步 .sql 文件中的 START_PICKUP_DATE 和 END_PICKUP_DATE 并等于 configurations.py 文件中的 START_TIME 和 END_TIME,这样我只需要更改 configurations.py 中的 START_TIME 和 END_TIME 并提取数据在不同的时间范围内使用 Snowflake 中的 a.sql。

我已经在网上寻找解决方案很长时间了,但仍然找不到适合我的问题的好的解决方案。非常感谢任何可以提供提示的人!

最佳答案

您应该能够参数化 sql 语句,这样您就可以将其作为在执行期间传递的参数,而不是在 SQL 文件中声明。

select supplier_confirmation_id, pickup_datetime, dropoff_datetime, pickup_station_distance
from SANDBOX.ZQIAN.V_PDL
where pickup_datetime >= %(START_PICKUP_DATE)s and pickup_datetime < %(END_PICKUP_DATE)s and supplier_confirmation_id is not null;

然后在调用该函数时,只需将参数START_PICKUP_DATEEND_PICKUP_DATE 作为参数传递给execute 语句即可。一种方法是执行从参数名称到参数值的映射。 (在这个例子中,我假设你有一个函数可以获取参数值)。

cur = cs.execute(query, {'START_PICKUP_DATE':get_value_from_config('start_pickup'), 'END_PICKUP_DATE':get_value_from_config('end_pickup')})

或者你可以按位置传递它们

cur = cs.execute(query, [get_value_from_config('start_pickup'), get_value_from_config('end_pickup')])

本质上变成了

cur = cs.execute(query, ['2018-10-01 00:00:00','2019-04-01 00:00:00'])

https://stackoverflow.com/questions/57465179/

相关文章:

vbscript - IBM PCOMM - 无法从另一个 vbs 宏中调用 vbs 宏

:0: error: could n">swift - 我在 cygwin 上得到 ":0: error: could n

angular - ionic `` 不适用于 domSanitizer, "Sa

azure - 我的域的 DNS 记录未通过 dns-01 质询在 azure-dns 上传播

python - 在 cmd 中使用 pip 安装 matplotlib 完成而没有实际安装

node.js - 当无效数据传递给模式时,mongoose 不会抛出错误

cordova - 为什么我无法在 ionic cordova 中安装 npm 包 cordova-

ruby-on-rails - Action 电缆检测多个连接/选项卡

c# - XUnit 和 ITestOutputHelper 实例化

postman - 使用来自 Postman 的 httpOnly cookie