如何使用Python遍历日期列表并循环执行含CTE的PostgreSQL 12 INSERT语句(支持多客户表)
需求与解决方案:遍历多日期+多客户表执行PostgreSQL插入操作
你现在的需求是把原本针对单客户表的批量插入逻辑,扩展成同时遍历多个客户表和多个日期,每个日期+客户表的组合都会生成2条插入记录(对应两个CTE)。咱们可以通过以下几步修改代码来实现:
关键修改点
- 把SQL中的固定表名
customers改成可动态替换的参数,适配不同客户表 - 给函数新增客户表列表参数,实现多表遍历
- 用嵌套循环先遍历表、再遍历日期,覆盖所有组合
- 执行SQL时同时传入
日期和表名两个参数
修改后的完整代码
import logging # 初始化日志 logging.basicConfig(level=logging.WARNING) log = logging.getLogger(__name__) def insert_data(date_list: list, table_list: list): # 把表名改成动态参数 %(table_name)s,适配不同客户表 sql_query = """WITH CTE1 as ( select date, count(*) from %(table_name)s where date = %(date)s group by date ), CTE2 as ( select date, count(*) from %(table_name)s where account_deleted is NULL and date = %(date)s group by date ) INSERT INTO customers_final (date, customers) select * from CTE1 union all select * from CTE2""" # 先检查表列表和日期列表是否有效 if not table_list: log.warning('客户表列表为空,无需执行') return if not date_list: log.warning('日期列表为空,无需执行') return # 嵌套循环:先遍历每个客户表,再遍历每个日期 for table_name in table_list: log.info(f'开始处理客户表: {table_name}') for date in date_list: params = {"date": date, "table_name": table_name} # 用mogrify安全处理表名参数(避免SQL注入,psycopg2专属方法) safe_sql = cursor.mogrify(sql_query, params).decode('utf-8') cursor.execute(safe_sql) log.info(f'已完成日期 {date} 在表 {table_name} 的插入操作') if __name__ == '__main__': # 示例日期列表 date_list = ['2021-03-29', '2021-03-28', '2021-03-27', '2021-03-26'] # 示例多客户表列表 table_list = ['customers_2021', 'customers_2022', 'customers_snapshot'] # 注意:需先初始化数据库连接和cursor(以psycopg2为例) # import psycopg2 # conn = psycopg2.connect("dbname=你的数据库名 user=用户名 password=密码") # cursor = conn.cursor() insert_data(date_list, table_list) # 最后提交事务并关闭连接 # conn.commit() # cursor.close() # conn.close()
重要说明
- 表名参数的安全处理:PostgreSQL的普通参数绑定不支持替换表名/列名,所以用
cursor.mogrify()来安全拼接表名,避免SQL注入风险,这比直接字符串格式化更可靠。 - 嵌套循环逻辑:外层遍历客户表,内层遍历日期,确保每个表的每个日期都执行一次插入,每个组合会生成2条记录(对应两个CTE的结果)。
- 空列表检查:提前检查表和日期列表是否为空,避免无效循环,同时用日志提示状态,方便排查问题。
内容的提问来源于stack exchange,提问作者Estrobelai
相关产品推荐
相关产品推荐

