2017-04-07 69 views
0

所以我是烧瓶/ sqlalchemy新手,但这看起来应该是一个非常简单的。然而,对于我的生活,我无法实现它的功能,并且我无法在网上找到任何文档。我有一个有点复杂的查询运行,返回一个数据库对象的列表。如何更新查询中返回的对象

items = db.session.query(X, func.count(Y.x_id).label('total')).filter(X.size >= size).outerjoin(Y, X.x_id == Y.x_id).group_by(X.x_id).order_by('total ASC')\ 
    .limit(20).all() 

当我得到这个项目列表后,我想循环遍历列表,并为每个项目更新它的一些属性。

for it in items: 
    it.some_property = 'xyz' 
    db.session.commit() 

但是发生的事情是,我得到一个错误

it.some_property = 'xyz' 
AttributeError: 'result' object has no attribute 'some_property' 

我没疯。我肯定该属性确实存在于从db.Model类型化的模型X上。即使我可以清楚地看到它们存在于调试器中,但有关查询的事情仍然阻止我访问属性。任何帮助,将不胜感激。

class X(db.Model): 
    x_id = db.Column(db.Integer, primary_key=True) 
    size = db.Column(db.Integer, nullable=False) 
    oords = db.relationship('Oords', lazy=True, backref=db.backref('x', lazy='joined')) 

    def __init__(self, capacity): 
     self.size = size 

回答

1

鉴于你比如你结果对象没有属性some_property,就像例外说。 (无论是做模型X对象,但我希望这只是在本例中的错误。)

他们有明确标示total作为第二列和模型X实例作为第一列。如果你的意思是访问XX实例的属性,访问首先从结果行,或者使用索引或隐式标签:

items = db.session.query(X, func.count(Y.x_id).label('total')).\ 
    filter(X.size >= size).\ 
    outerjoin(Y, X.x_id == Y.x_id).\ 
    group_by(X.x_id).\ 
    order_by('total ASC').\ 
    limit(20).\ 
    all() 

# Unpack a result object 
for x, total in items: 
    x.some_property = 'xyz' 

# Please commit after *all* the changes. 
db.session.commit() 

正如其他答案指出,你可以使用bulk operations作为好吧,虽然你的limit(20)会让这更具挑战性。

+0

这正是我所期待的。谢谢。 – dcole2929

+0

修正用for循环中的实例覆盖类变量。从最初写'it.X'的想法留下来,但是随后就是解包。 –

1

您应该使用更新功能。

就像是:

from sqlalchemy import update 

stmt = update(users).where(users.c.id==5).\ 
     values(name='user #5') 

或者:

session = self.db.get_session() 
session.query(Organisation).filter_by(id_organisation = organisation.id_organisation).\ 
update(
    { 
     "name" : organisation.name, 
     "type" : organisation.type, 
    }, synchronize_session = False) 
session.commit(); 
session.close() 

的SQLAlchemy的文档:http://docs.sqlalchemy.org/en/latest/core/dml.html