Psycopg2无法找到连接块内创建的临时表问题排查
解决psycopg2使用临时表时copy_from提示表不存在的问题
问题原因
- 表名参数错误:你的
copy_from调用中传入的是变量temp_table(即创建临时表的SQL语句字符串),而非实际表名字符串"temp_table",导致PostgreSQL查找错误的表名。 - search_path未包含临时表模式:临时表默认创建在
pg_temp模式下,你设置search_path TO test后,PostgreSQL只会在test模式下查找表,无法定位到pg_temp中的临时表。
修复方案
修改代码如下,解决上述两个问题:
import psycopg2 from io import StringIO pg_connection = { "dbname": "test", "user": "testuser", "password": "testpass", "host": "localhost" } conn = psycopg2.connect(**pg_connection) conn.autocommit = False # 确保所有操作在同一个事务内 try: with conn.cursor() as curr: # 将pg_temp加入search_path,优先查找临时表 curr.execute("SET search_path TO pg_temp, test") # 创建临时表(注意指定永久表的模式,避免search_path影响) temp_table_stmt = """ CREATE TEMP TABLE temp_table ON COMMIT DROP AS SELECT * FROM public.target_table WHERE false; """ curr.execute(temp_table_stmt) # 模拟CSV数据缓冲区 fileobj = StringIO("val1,val2\nval3,val4\n") columns = ["column1", "column2"] # 这里传入正确的表名字符串"temp_table" curr.copy_from(fileobj, "temp_table", columns=columns, sep=',') # 执行upsert到永久目标表 upsert_stmt = """ INSERT INTO public.target_table (column1, column2) SELECT column1, column2 FROM temp_table ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2; """ curr.execute(upsert_stmt) conn.commit() except Exception as e: conn.rollback() raise e finally: conn.close()
关键细节说明
- 临时表的作用域是当前会话/事务,你的操作逻辑本身是可行的,无需修改PostgreSQL配置。
- 将
pg_temp放在search_path首位,既可以让PostgreSQL优先找到临时表,也能避免和同名永久表冲突。 - 创建临时表时,显式指定永久表的模式(如
public.target_table),防止search_path设置导致找不到源表。
内容的提问来源于stack exchange,提问作者user3299166
相关产品推荐
相关产品推荐

