2017-04-07 65 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