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

如何在Python导入CSV到PostgreSQL时添加文件名与时间戳

解决CSV导入数据库时补充文件名和数据插入时间的问题

以下是几种实用的实现方案,根据你的数据量和场景选择:

方案一:临时表中转(大数据量首选)

利用临时表先导入原始CSV数据,再批量插入到目标表时补充文件名和时间戳,保留copy_from的高效性:

import psycopg2
from datetime import datetime

# 连接数据库
conn = psycopg2.connect("dbname=你的数据库名 user=你的用户名")
cur = conn.cursor()
csv_filename = 'my.csv'
load_time = datetime.now()

# 创建与CSV列匹配的临时表(请替换为你的实际列名和类型)
cur.execute("""
CREATE TEMP TABLE temp_csv_import (
    col1 TEXT,
    col2 INT,
    col3 NUMERIC
)
""")

# 导入CSV到临时表
with open(csv_filename, 'r') as f:
    next(f)  # 跳过CSV表头
    cur.copy_from(f, 'temp_csv_import', sep=',')

# 批量插入到目标表,同时补充文件名和时间戳
cur.execute("""
INSERT INTO csv_import (col1, col2, col3, filename, load_timestamp)
SELECT col1, col2, col3, %s, %s
FROM temp_csv_import
""", (csv_filename, load_time))

# 提交并关闭连接
conn.commit()
cur.close()
conn.close()

方案二:Python预处理每行数据(小数据量直接用)

直接读取CSV每行数据,追加文件名和时间戳后用executemany插入,逻辑简单直观:

import psycopg2
from datetime import datetime
import csv

conn = psycopg2.connect("dbname=你的数据库名 user=你的用户名")
cur = conn.cursor()
csv_filename = 'my.csv'
load_time = datetime.now()

# 读取并预处理CSV数据
with open(csv_filename, 'r') as f:
    reader = csv.reader(f)
    next(reader)  # 跳过表头
    # 给每行追加文件名和时间戳
    processed_data = [row + [csv_filename, load_time] for row in reader]

# 批量插入到目标表
cur.executemany("""
INSERT INTO csv_import (col1, col2, col3, filename, load_timestamp)
VALUES (%s, %s, %s, %s, %s)
""", processed_data)

conn.commit()
cur.close()
conn.close()

方案三:用StringIO模拟CSV文件(中等数据量兼顾效率)

把预处理后的数据写入StringIO对象,再用copy_from导入,既保留COPY的高效性,又不用创建临时表:

import psycopg2
from datetime import datetime
import csv
from io import StringIO

conn = psycopg2.connect("dbname=你的数据库名 user=你的用户名")
cur = conn.cursor()
csv_filename = 'my.csv'
# 转成字符串格式,适配COPY的文本输入
load_time_str = datetime.now().isoformat()

output = StringIO()
writer = csv.writer(output, delimiter=',')

# 读取原始CSV并追加字段
with open(csv_filename, 'r') as f:
    reader = csv.reader(f)
    next(reader)  # 跳过表头
    for row in reader:
        row.append(csv_filename)
        row.append(load_time_str)
        writer.writerow(row)

# 回到模拟文件的开头
output.seek(0)
# 指定目标表的所有列,确保顺序匹配
cur.copy_from(
    output, 
    'csv_import', 
    sep=',', 
    columns=('col1', 'col2', 'col3', 'filename', 'load_timestamp')
)

conn.commit()
cur.close()
conn.close()

方案选择建议

  • 数据量较大(10w行以上):优先用临时表中转,COPY的效率远高于逐行插入
  • 数据量较小(1w行以内):用Python预处理每行,代码更简洁
  • 中等数据量:用StringIO模拟文件,平衡效率和代码复杂度

内容的提问来源于stack exchange,提问作者Arpit Rathod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:05:31