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

Python使用psycopg操作Postgres时出现BuildingStairs重复插入问题

问题根本原因

问题出在Python可变默认参数的特性陷阱:函数/方法的默认参数是在代码定义阶段完成初始化的,而非每次调用方法时重新创建。
你在Building类的__init__方法中设置了默认参数stairs_list=[],这就导致所有未显式传入stairs_list参数的Building实例,都会共用同一个列表对象,每次往实例的stairs_list追加元素,本质上都是往同一个全局共享的列表里加数据。

逻辑验证(和实际插入结果完全匹配)

  1. 创建building1,共用列表初始为空,追加A栋0层楼梯后列表为[A栋0层],调用save方法插入1条数据:(A,0)
  2. 创建building2,复用已有内容的共享列表,追加B栋1、2层后列表为[A栋0层, B栋1层, B栋2层],调用save方法插入3条数据:(A,0)、(B,1)、(B,2)
  3. 创建building3,复用已有内容的共享列表,追加C栋3层后列表为[A栋0层, B栋1层, B栋2层, C栋3层],调用save方法插入4条数据:(A,0)、(B,1)、(B,2)、(C,3)
    三次插入累加后,就得到了你看到的重复数据结果。

修复方案

  1. 修改Building类的初始化方法,把可变默认参数改成None,每次实例化时单独创建空列表:
class Building:
    def __init__(self, building_name=None, stairs_list=None):
        self.building_name = building_name
        # 每次实例化单独生成新列表,避免共用
        self.stairs_list = stairs_list if stairs_list is not None else []
  1. 额外优化:不要用字符串拼接的方式生成SQL语句,存在SQL注入风险,改用psycopg原生的参数化查询写法:
# 原写法(有风险)
cur.execute("""INSERT INTO test_building_name(builing_name) VALUES('%s')"""%self.building_name)
# 优化后写法
cur.execute("INSERT INTO test_building_name(builing_name) VALUES(%s)", (self.building_name,))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:54:02