使用SQLAlchemy ORM更新行

时间:2017-12-10 02:36:50

标签: python sqlalchemy

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

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

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

但是我收到错误说:

AttributeError: 'FoobarModel' object has no attribute 'update'

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

foobar = session.query(FoobarModel).get(foobar_id)
foobar.name = 'New Foobar Name!'
session.commit()
session.flush()

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

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()

但是我得到了这个错误:

TypeError: 'FoobarModel' object does not support item assignment

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

print(old_foobar['name'])

引发错误:

TypeError: 'FoobarModel' object is not subscriptable

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

2 个答案:

答案 0 :(得分:11)

我相信您正在为更新查询寻找类似的内容:

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

由于update()属于Query,而filter()确实会返回Query个对象,这样做会有效,这与尝试呼叫update() { FoobarModelsee also here返回的{1}}对象(没有此类函数)。

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

setattr

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

答案 1 :(得分:0)

工作

device = models.Device.query.filter(models.Device.device_identifier == device_identifier).first()

setattr(device, 'updated_at', datetime.now())
setattr(device, 'ip_address', ip_address)
db.session.commit()

没用

device.is_active = True
device.id_address = ip_address
device.updated_at = datetime.now()
print(device.ip_address)
db.session.commit()