使用WHERE在SQLAlchemy Core中进行批量更新
我已经成功地在SQLAlchemy中使用批量插入,像这样:
conn.execute(addresses.insert(), [
{'user_id': 1, 'email_address' : 'jack@yahoo.com'},
{'user_id': 1, 'email_address' : 'jack@msn.com'},
{'user_id': 2, 'email_address' : 'www@www.org'},
{'user_id': 2, 'email_address' : 'wendy@aol.com'},
])
现在我需要一个类似的功能来更新数据。我尝试了这个:
conn.execute(addresses.insert(), [
{'user_id': 1, 'email_address' : 'jack@yahoo.com', 'id':12},
{'user_id': 1, 'email_address' : 'jack@msn.com', 'id':13},
{'user_id': 2, 'email_address' : 'www@www.org', 'id':14},
{'user_id': 2, 'email_address' : 'wendy@aol.com', 'id':15},
])
我希望每一行都能根据'id'字段进行更新,但它并没有生效。我猜这可能是因为我没有指定WHERE条件,但我不知道如何用字典中的数据来指定这个WHERE条件。
有人能帮我吗?
5 个回答
0
根据上面的回答,我成功解决了问题,因为SQLAlchemy(一个数据库工具)说我需要加上synchronize_session=None这个参数。
我用以下代码做出了正确的处理。
values= {"id" : results.id, "user_id": results.id}
if user.email is not None:
values['email'] = user.email
if user.first_name is not None:
values['first_name'] = user.first_name
if user.last_name is not None:
values['last_name'] = user.last_name
else:
values['last_name'] = results.last_name
update_user_q = update(u).where(u.id == bindparam("user_id")).values(
email=bindparam("email"),
first_name=bindparam("first_name"), last_name=bindparam("last_name")).execution_options(
synchronize_session=None)
db.execute(update_user_q, [
values]
)
db.commit()
别忘了在你的数据中传入主键。
3
@Jongbin Park 的解决方案确实对我有用,特别是在使用复合主键的情况下。(这是在 Azure SQL Server 上)
update_vals = []
update_vals.append(dict(Name='name_a', StartDate='2020-05-26 20:17:32', EndDate='2020-05-26 20:46:03', Comment='TEST COMMENT 1'))
update_vals.append(dict(Name='name_b', StartDate='2020-05-26 21:31:16', EndDate='2020-05-26 21:38:37', Comment='TEST COMMENT 2'))
s.bulk_update_mappings(MyTable, update_vals)
s.commit()
这里的 Name、StartDate 和 EndDate 都是复合主键的一部分。'Comment' 是要在数据库中更新的值。
4
在2023年,SQLAlchemy 2.0 更新了它的接口:
from sqlalchemy import update
session.execute(
update(User),
[
{"id": 1, "fullname": "Spongebob Squarepants"},
{"id": 3, "fullname": "Patrick Star"},
{"id": 5, "fullname": "Eugene H. Krabs"},
],
)
34
这个会话里有两个功能,分别叫做 bulk_insert_mappings
和 bulk_update_mappings
。你可以在这里找到相关的 文档。
需要注意的是,在使用这些功能时,你必须在映射中提供主键。
# List of dictionary including primary key
user_mappings = [{
'user_id': 1, # This is pk?
'email_address': 'jack@yahoo.com',
'_id': 1
}, ...]
session.bulk_update_mappings(User, user_mappings)
session.commit()
89
请阅读使用Core更新和删除行这个教程部分。下面的代码可以帮助你入门:
from sqlalchemy import bindparam
stmt = addresses.update().\
where(addresses.c.id == bindparam('_id')).\
values({
'user_id': bindparam('user_id'),
'email_address': bindparam('email_address'),
})
conn.execute(stmt, [
{'user_id': 1, 'email_address' : 'jack@yahoo.com', '_id':1},
{'user_id': 1, 'email_address' : 'jack@msn.com', '_id':2},
{'user_id': 2, 'email_address' : 'www@www.org', '_id':3},
{'user_id': 2, 'email_address' : 'wendy@aol.com', '_id':4},
])