使用 Python 3.8 将时间戳插入雪花

时间:2021-04-30 23:10:39

标签: python-3.x snowflake-cloud-data-platform

我在雪花中定义了一个空表;

CREATE OR REPLACE TABLE db1.schema1.table(
ACCOUNT_ID NUMBER NOT NULL PRIMARY KEY,
PREDICTED_PROBABILITY FLOAT,
TIME_PREDICTED TIMESTAMP
);

它创建了正确的表,该表已使用 sql 中的 desc 命令进行检查。然后使用雪花 python 连接器,我们尝试执行以下查询;

insert_query =  f'INSERT INTO DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES(ACCOUNT_ID, PREDICTED_PROBABILITY, TIME_PREDICTED) VALUES ({accountId}, {risk_score},{ct});'
ctx.cursor().execute(insert_query)

就在此查询之前定义变量,主要挑战是将当前时间戳写入雪花。这里 ct 的值定义为;

import datetime
ct = datetime.datetime.now()
print(ct)

2021-04-30 21:54:41.676406

但是当我们尝试执行这个 INSERT 查询时,我们得到以下错误消息;


ProgrammingError: 001003 (42000): SQL compilation error:
syntax error line 1 at position 157 unexpected '21'.

我可以在这里获得一些帮助来格式化日期时间值吗?感谢帮助。

3 个答案:

答案 0 :(得分:0)

有根据的猜测。执行插入时:

insert_query =  f'INSERT INTO ...(ACCOUNT_ID, PREDICTED_PROBABILITY, TIME_PREDICTED) 
VALUES ({accountId}, {risk_score},{ct});'

这是一个字符串插值。 ct 作为日期时间的字符串表示形式提供,与时间戳数据类型不匹配,因此出错。

我建议改用正确的 variable binding

ctx.cursor().execute("INSERT INTO DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES "
                     "(ACCOUNT_ID, PREDICTED_PROBABILITY, TIME_PREDICTED) "
                     "VALUES(:1, :2, :3)",
                      (accountId,
                       risk_score, 
                       ("TIMESTAMP_LTZ", ct) 
                      )
                   );

<块引用>

Avoid SQL Injection Attacks

避免使用 Python 的格式化函数绑定数据,因为这会带来 SQL 注入的风险。例如:

# Binding data (UNSAFE EXAMPLE)
con.cursor().execute(
    "INSERT INTO testtable(col1, col2) "
    "VALUES({col1}, '{col2}')".format(
        col1=789,
        col2='test string3')
    )

相反,将值存储在变量中,检查这些值(例如,通过查找字符串中可疑的分号),然后使用 qmark 或数字绑定样式绑定参数。

答案 1 :(得分:0)

除了@Lukasz 提供的答案之外,您还可以考虑将 current_timestamp() 定义为 TIME_PREDICTED 列的默认值:

CREATE OR REPLACE TABLE db1.schema1.table(
ACCOUNT_ID NUMBER NOT NULL PRIMARY KEY,
PREDICTED_PROBABILITY FLOAT,
TIME_PREDICTED TIMESTAMP DEFAULT current_timestamp
);

然后只需插入 ACCOUNT_ID 和 PREDICTED_PROBABILITY:

insert_query =  f'INSERT INTO DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES(ACCOUNT_ID, PREDICTED_PROBABILITY) VALUES ({accountId}, {risk_score});'
ctx.cursor().execute(insert_query)

它会自动将插入时间分配给 TIME_PREDICTED

答案 2 :(得分:0)

您忘记在 {ct} 前后放置引号。代码应该是:

insert_query =  "INSERT INTO DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES(ACCOUNT_ID, PREDICTED_PROBABILITY, TIME_PREDICTED) VALUES ({accountId}, {risk_score},'{ct}');".format(accountId=accountId,risk_score=risk_score,ct=ct)
ctx.cursor().execute(insert_query)