使用SQLAlchemy ORM更新行

Kyl*_*gan 3 python sqlalchemy

注意:我没有在这里使用Flask-SQLAlchemy,我正在使用SQLAlchemy ORM

我在StackOverflow上看到了几个答案,说这是一种更新记录的方法:

session.query(FoobarModel).get(foobar_id).update({'name': 'New Foobar Name!'})
Run Code Online (Sandbox Code Playgroud)

但是我得到一个错误说:

AttributeError: 'FoobarModel' object has no attribute 'update'
Run Code Online (Sandbox Code Playgroud)

我能够像这样更新,但是:

foobar = session.query(FoobarModel).get(foobar_id)
foobar.name = 'New Foobar Name!'
session.commit()
session.flush()
Run Code Online (Sandbox Code Playgroud)

所以我尝试了这样的事情(所以我不必写出每个属性):

new_foobar = {'name': 'New Foobar Name!'}
old_foobar = session.query(FoobarModel).get(foobar_id)

for property in new_foobar:
  old_foobar[property] = new_foobar[property]

session.commit()
session.flush()
Run Code Online (Sandbox Code Playgroud)

但是我得到了这个错误:

TypeError: 'FoobarModel' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)

在做了一些挖掘之后我发现它是因为即使这样也行不通:

print(old_foobar['name'])
Run Code Online (Sandbox Code Playgroud)

哪个引发错误:

TypeError: 'FoobarModel' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)

老实说,在我看来,第一种语法是最好的,但我无法让它发挥作用.有任何想法吗?

bgs*_*gse 12

我相信你正在为你的更新查询寻找这样的东西:

session.query(FoobarModel).filter(FoobarModel.id == foobar_id).update({'name': 'New Foobar Name!'})
Run Code Online (Sandbox Code Playgroud)

由于update()属于Query,并且filter()确实返回了一个Query对象,这将起作用,与试图调用返回update()FoobarModel对象(没有这样的函数)相反Query.get(),另请参见此处.

至于循环您的属性并按名称分配它们,您可以使用setattr和dict 执行此操作,如下所示:

foobar = session.query(FoobarModel).get(foobar_id)

props = {'name': 'my new name'}

for key, value in props.items():
    setattr(foobar, key, value)

session.commit()
session.flush()
Run Code Online (Sandbox Code Playgroud)

对于一个属性来说,这显然有点无意义,但也许它会在某些时候派上用场.