繁体   English   中英

如何通过 python 字典更新 sqlalchemy orm object

[英]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_byid来保存一个数据库调用以获取特定行,并使用您最初想要的字典更新它。

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动态更新列,还可以将动态表和列与getattrsetattr结合使用

例子:

# 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获得有关setattrgetattrhasattr更多信息

https://docs.python.org/2/library/functions.html#getattr

https://docs.python.org/2/library/functions.html#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM