存在一个表用户,在我的代码中,我有一个很大的User对象列表。要插入它们,我可以使用:
session.add_all(user_list)
session.commit()
问题是我想要更新几个重复项,但数据库不允许插入重复的条目。当然,我可以迭代 user_list 并尝试在数据库中插入用户,如果失败 - 更新它:
for u in users:
q = session.query(T).filter(T.fullname==u.fullname).first()
if q:
session.query(T).filter_by(index=q.index).update({column: getattr(u,column) for column in Users.__table__.columns.keys() if column!='id'})
session.commit()
else:
session.add(u)
session.commit()
但是我发现这个解决方案安静无效:首先,我正在提出几个检索对象 q 的请求,而不是批量插入新项目,我每个插入一个。我想知道是否有更好的解决方案来完成这项任务。
UPD 更好的版本:
for u in users:
q = session.query(T).filter(Users.fullname==u.fullname).first()
if q:
for column in Users.__table__.columns.keys():
if not column=='index':
setattr(q,column,getattr(u,column))
session.add(q)
else:
session.add(u)
session.commit()
答案 0 :(得分:0)
更好的解决方案是使用
INSERT ... ON DUPLICATE KEY UPDATE ...
批量 MySQL构造(我假设您正在使用MySQL,因为您的帖子标记为' mysql')。这样您就可以在一个语句/事务中插入新条目并更新现有条目,请参阅http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
如果您有多个唯一索引,并且根据您的架构,您必须填写所有NOT NULL值(因此在调用它之前发出一个批量SELECT),这不是理想的,但它&# 39;绝对是最有效的选择,我们经常使用它。批量版本看起来像(让我们假设name
是一个唯一的密钥):
INSERT INTO User (name, phone, ...) VALUES
('ksmith', '111-11-11', ...),
('jford', '222-22,22', ...),
...,
ON DUPLICATE KEY UPDATE
phone = VALUES(phone),
... ;
不幸的是,SQLA本身不支持INSERT ... ON DUPLICATE KEY UPDATE ...
,因此您必须实现一个小帮助函数,它将为您构建查询。