Python SQLAlchemy-Session.merge()返回重复密钥完整性错误

Python SQLAlchemy-Session.merge()返回重复密钥完整性错误,python,mysql,sqlalchemy,Python,Mysql,Sqlalchemy,我正在尝试根据CSV文件中的信息插入或更新一些数据库行。我能够将CSV文件读入dict()对象列表,并将这些dict处理为类对象。但是,尝试对这些对象执行会话.merge(),会出现以下错误: sqlalchemy.exc.IntegrityError: (MySQLdb._exceptions.IntegrityError) (1062, "Duplicate entry '27445-5810' for key 'SiteId'") 以前使用sqlalchemy时,merge()会在插入失

我正在尝试根据CSV文件中的信息插入或更新一些数据库行。我能够将CSV文件读入dict()对象列表,并将这些dict处理为类对象。但是,尝试对这些对象执行
会话.merge()
,会出现以下错误:

sqlalchemy.exc.IntegrityError: (MySQLdb._exceptions.IntegrityError) (1062, "Duplicate entry '27445-5810' for key 'SiteId'")
以前使用sqlalchemy时,
merge()
会在
插入失败时自动执行
更新。在这种情况下,为什么会出现完整性错误

这是我的剧本:

从sqlalchemy导入创建引擎和函数
从sqlalchemy.orm导入sessionmaker
从sqlalchemy.ext.automap导入automap_base
从io导入StringIO
从csv导入读取器
导入xmltodict
从请求导入获取
从json导入加载
从系统导入argv
从datetime导入datetime,timedelta
从回溯导入打印exc
从TQM导入TQM
#设置数据库连接/类
引擎=创建引擎(
""
)
基本=自动映射基本()
基础准备(发动机,反射=真实)
ProductSource=Base.classes.ProductSource
Products=Base.classes.Products
Session=sessionmaker()
如果argv else输入中的“site”('siteid:'),则siteid=argv[2]
def_findhead(obj,钥匙):
如果输入obj:返回obj[输入]
对于对象项()中的v:
如果存在(v,dict):
项目=_findhead(v,键)
如果项目不是无:
退货项目
连接=会话(绑定=引擎)
source=conn.query(ProductSource).filter(ProductSource.SiteId==SiteId).first()
feed_file=get(source.Url).text
映射=加载(source.CsvMap)
尝试:
如果source.FileType==“csv”:
分隔符={
'逗号':',',
“选项卡”:“\t”,
“管道”:“|”,
“分号”:“;”
}
将StringIO(feed_文件)作为f:
产品=列表(读卡器(f,分隔符=分隔符[source.Other]))
其他:
parsed=xmltodict.parse(提要文件)
products=\u findhead(已解析,source.HeadElement)
除:
康涅狄格州关闭
打印('格式错误的文件,无法读取此提要')
出口(1)
已更新=0
失败=0
有效的_键=[]
started=datetime.now()
source.Started=Started
source.Updated=已更新
康涅狄格州提交
对于映射中的键。键():
如果映射[键]!=无:
有效的\u键。追加(键)
如果“说明”不在有效的\u密钥中或“产品ID”不在有效的\u密钥中:
打印('映射无效,无需执行')
康涅狄格州关闭
出口(1)
对于TQM中的产品(产品):
尝试:
新产品行={'SiteId':SiteId}
对于有效_密钥中的密钥:
新产品行[键]=产品[映射[键]]
连接合并(产品(**新产品行))
康涅狄格州提交
更新+=1
除:
控制点回滚()
失败+=1
finished=datetime.now()
下一次读取=开始+时间增量(天=源.ReadInterval)
source.LastRead=已完成
source.NextRead=下一次读取
source.Added=已添加
source.Updated=已更新
康涅狄格州提交
打印(f'{source.Updated}产品更新')
打印(f'{failed}产品失败')
康涅狄格州关闭

SiteId是主键还是唯一的受约束列?它是唯一的受约束列。有一个主键,一个名为
id
的列。但是在
SiteId
ProductId
上有一个独特的约束。每个
SiteId
会话只能存在一个给定的
ProductId
。merge()
只考虑主键。