[英]How to update sqlalchemy orm object by a python dict
字典的键名映射到 sqlalchemy object 属性
前任:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
可以从 id = 3, {name: "diana"}
或 id = 15, {name: "marchel", fullname: "richie marchel"}
您可以使用setattr()
动态更新现有 SQLAlchemy 对象上的属性:
user = session.query(User).get(someid)
for key, value in yourdict.iteritems():
setattr(user, key, value)
我这里有另一个解决方案。 如下定义模型方法会很方便。
class ModelName(db.Model):
"""
docstring here
"""
...
def update(self, **kwargs):
for key, value in kwargs.items():
if hasattr(self, key):
setattr(self, key, value)
我希望它能解决你的问题。
谢谢
根据您的用例(如果您不需要验证或推断模型中的任何内容),您可以通过使用filter_by
和id
来保存一个数据库调用以获取特定行,并使用您最初想要的字典更新它。
user_query = session.query(User).filter_by(id=someid)
data_to_update = dict(name="marchel", fullname="richie marchel")
user_query.update(data_to_update)
您可能还需要将synchronize_session=False
关键字参数添加到您的update
调用中,具体取决于您的会话类型(如果您使用scoped_session
):
user_query.update(data_to_update, synchronize_session=False)
根据@martijn-pieters 的回答,您不仅可以使用setattr
动态更新列,还可以将动态表和列与getattr
和setattr
结合使用
例子:
# models.py
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
# update.py
import models
def dynamic_update(dynamic_table, col_id, dynamic_cols):
"""
dynamic_table: name of the table, "User" for example
col_id: id of which column you want to update
dynamic_cols: key value pairs {name: "diana"}
"""
if hasattr(models, dynamic_table):
table = getattr(models, dynamic_table)
col_info = table.query.filter_by(id=col_id).first()
for (key, value) in dynamic_cols.items():
if hasattr(table, key):
setattr(col_info, key, value)
session.commit()
顺便说一句,您可以从 python 官方文档https://docs.python.org/2/library/functions.html#setattr获得有关setattr
、 getattr
、 hasattr
更多信息
我认为最简单的方法是使用带有filter
sqlalchemy update
def update_item(db: Session, item_id: int, item: ItemUpdate):
db.query(Item).filter(id=item_id).update(item.dict())
db.commit()
确保您始终对主键进行过滤,以避免更新多于一行。 这可以作为在提交会话之前检查代码来完成。
在 sqlalchemy 2.0 API 中,您可以使用:
stmt = update(User).where(User.name == "john").values(**your_data)
session.execute(stmt)
我在使用 flask-sqlalchemy 时发现了这个解决方案,然后在 sqlalchemy 上对其进行了测试,它也同样有效:
dict = {name: "marchel", fullname: "richie marchel"}
session.execute(update(User).filter_by(id=3).values(**dict))
session.commit()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.