如何在Redshift的INSERT语句中使用GETDATE()添加时间戳?
解决Redshift插入时"ROW expression not supported"错误并添加时间戳
错误原因
- 你把
GETDATE()用单引号包裹,导致它被识别为字符串字面量而非函数调用,插入的是字符串"GETDATE()"而非实际时间戳。 - 批量生成大量
VALUES行时,Redshift会将其解析为ROW表达式,触发不支持的报错。
解决方案
方案1:修正GETDATE()写法(简单但需注意行数限制)
去掉GETDATE()的单引号,让Redshift执行函数:
values_ = ', '.join([f"('{str(i.columnA)}','{str(i.columnB)}','{str(i.columnC)}','{str(i.columnD)}', GETDATE())" for i in df2.itertuples()]) sqlexecute(f'''insert into table.table2 (columnA, columnB, columnC, columnD, time_) values {values_} ; ''')
注意:如果DataFrame行数过多(比如上万行),仍可能触发原错误,建议搭配其他方案。
方案2:改用INSERT ... SELECT + UNION ALL(避免ROW表达式问题)
用UNION ALL拼接每行的SELECT语句,绕过VALUES的ROW表达式限制:
select_rows = '\nUNION ALL\n'.join([ f"SELECT '{str(i.columnA)}', '{str(i.columnB)}', '{str(i.columnC)}', '{str(i.columnD)}', GETDATE()" for i in df2.itertuples() ]) sqlexecute(f'''insert into table.table2 (columnA, columnB, columnC, columnD, time_) {select_rows} ; ''')
方案3:设置列默认值(最优解)
如果有权限修改表结构,直接给time_列设置默认值为GETDATE(),插入时无需手动指定该列:
-- 先执行一次修改表结构的SQL ALTER TABLE table.table2 ALTER COLUMN time_ SET DEFAULT GETDATE();
之后插入代码简化为:
values_ = ', '.join([f"('{str(i.columnA)}','{str(i.columnB)}','{str(i.columnC)}','{str(i.columnD)}')" for i in df2.itertuples()]) sqlexecute(f'''insert into table.table2 (columnA, columnB, columnC, columnD) values {values_} ; ''')
方案4:参数化批量插入(最安全,防SQL注入)
使用参数化查询替代字符串拼接,既避免注入风险,也能绕过ROW表达式问题:
# 整理参数列表,无需包含时间列 params = [ (str(i.columnA), str(i.columnB), str(i.columnC), str(i.columnD)) for i in df2.itertuples() ] # 假设sqlexecute支持executemany模式(如基于psycopg2) sqlexecute(''' insert into table.table2 (columnA, columnB, columnC, columnD, time_) values (%s, %s, %s, %s, GETDATE()) ''', params, many=True)
内容的提问来源于stack exchange,提问作者kgk
相关产品推荐
相关产品推荐

