如何通过Python字典更新SQLAlchemy ORM对象

56 投票
9 回答
58133 浏览
提问于 2025-04-18 03:15

字典里的键名对应的是sqlalchemy对象的属性

举个例子:

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"}

9 个回答

3

在sqlalchemy 2.0的API中,你可以使用:

from sqlalchemy import update

stmt = update(User).where(User.name == "john").values(**your_data)
session.execute(stmt)
5

根据@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的官方文档中获取更多关于setattrgetattrhasattr的信息,链接如下:

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

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

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

17

根据你的使用情况(如果你不需要从模型中验证或推断任何东西),你可以通过使用 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)

你可能还需要在你的 update 调用中添加 synchronize_session=False 这个参数,这取决于你的会话类型(如果你使用 scoped_session):

user_query.update(data_to_update, synchronize_session=False)
30

我这里有另一个解决方案。定义模型的方法可以这样写。

class ModelName(db.Model):
    """
    docstring here
    """
    ...

    def update(self, **kwargs):
        for key, value in kwargs.items():
            if hasattr(self, key):
                setattr(self, key, value)

我希望这能解决你的问题。

谢谢你

78

你可以使用 setattr() 来动态更新一个已经存在的 SQLAlchemy 对象的属性:

user = session.query(User).get(someid)

for key, value in yourdict.items():
    setattr(user, key, value)

撰写回答