AWS Lambda中Python用psycopg2操作PostgreSQL插入数据失败
问题原因与解决方案
这个问题的核心是事务未提交,结合psycopg2的默认行为和Lambda的执行特性,具体分析如下:
为什么数据没插入但序列会自增?
- psycopg2默认会自动开启事务,所有SQL操作都在事务中执行。你执行完
INSERT语句后没有显式提交事务,当Lambda函数执行结束时,数据库连接会被自动关闭,此时未提交的事务会被自动回滚,所以插入的数据不会被持久化到表中。 - 而PostgreSQL的自增序列(比如
serial或identity类型的列),其nextval()操作是即时生效且不随事务回滚的——这是序列的设计特性,用来避免并发场景下的ID冲突,所以即使事务回滚,序列的数值依然会自增,这就导致了你看到的"ID序列涨了但表没数据"的现象。
为什么其他工具执行正常?
像psql命令行、pgAdmin这类工具,默认是开启**自动提交(autocommit)**模式的,每执行一条SQL语句后会自动提交事务,所以插入的数据能直接保存到表中。
代码修改方案
你需要在执行INSERT后显式提交事务,同时要注意正确管理数据库连接和游标资源,避免泄漏。这里提供两种可靠的修改方式:
方式1:显式提交事务(推荐生产环境使用)
调整代码,保留连接对象并在执行完插入后提交事务:
import psycopg2 import json def db(): with open('configEC2.json') as json_data_file: POSTGRES = json.load(json_data_file) db = psycopg2.connect( host=POSTGRES["sql"]["host"], user=POSTGRES["sql"]["user"], password=POSTGRES["sql"]["passwd"], dbname=POSTGRES["sql"]["db"] ) return db def dbSetup(): dbR = db() cur = dbR.cursor() return dbR, cur # 同时返回连接和游标 # 主逻辑 conn, cur = dbSetup() try: cur.execute("INSERT INTO table (column1, column2, column3) VALUES ('test1', 'test2', 'test3');") conn.commit() # 关键:提交事务 finally: # 确保资源被正确释放 cur.close() conn.close()
方式2:开启自动提交(适合单语句简单场景)
如果你的Lambda函数只执行单条SQL语句,可以在创建连接时开启自动提交模式:
def db(): with open('configEC2.json') as json_data_file: POSTGRES = json.load(json_data_file) db = psycopg2.connect( host=POSTGRES["sql"]["host"], user=POSTGRES["sql"]["user"], password=POSTGRES["sql"]["passwd"], dbname=POSTGRES["sql"]["db"] ) db.autocommit = True # 开启自动提交 return db # 后续执行代码无需手动commit cur = dbSetup() cur.execute("INSERT INTO table (column1, column2, column3) VALUES ('test1', 'test2', 'test3');") cur.close()
注意:自动提交模式不适合包含多条SQL的复杂事务场景,因为无法回滚部分操作,所以优先推荐方式1。
内容的提问来源于stack exchange,提问作者Honza Nijaký
相关产品推荐
相关产品推荐

