如何通过python dict更新sqlalchemy orm对象

cha*_*787 24 python orm sqlalchemy

dict的关键名称映射到sqlalchemy对象attrs

例如:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    password = Column(String)
Run Code Online (Sandbox Code Playgroud)

可以从id = 3 {name: "diana"}或id = 15更新,{name: "marchel", fullname: "richie marchel"}

Mar*_*ers 37

您可以使用setattr()动态更新现有SQLAlchemy对象的属性:

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

for key, value in yourdict.iteritems():
    setattr(user, key, value)
Run Code Online (Sandbox Code Playgroud)

  • @RichardWong:但考虑到会话在缓存和跟踪更新方面非常复杂.如果您选择绕过它,则必须确保也使会话缓存无效. (2认同)

Per*_*ect 7

我这里有另一个解决方案.将模型方法定义如下是很方便的.

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

    def update(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
Run Code Online (Sandbox Code Playgroud)

我希望它能解决你的问题.

谢谢


vin*_*ian 6

根据@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()
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你可以得到更多的信息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

  • 警告:如果更新同一模型上的多个字段,这将在同一模型中的每个字段更改上“提交”,**显着损害性能**(并且不必要地)。 (2认同)

she*_*eba 6

根据您的用例(如果您不需要验证或推断模型中的任何内容),可以使用filter_bywith 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)
Run Code Online (Sandbox Code Playgroud)

您可能还需要synchronize_session=Falseupdate通话中添加关键字参数,具体取决于会话的类型(如果使用scoped_session):

user_query.update(data_to_update, synchronize_session=False)
Run Code Online (Sandbox Code Playgroud)