2012-07-15 43 views
0

我一直在使用SQLAlchemy連接到MySQL數據庫。到目前爲止它一直運行良好,但我遇到了一些麻煩。我想在我的一個類中調用一個方法,在查詢後會分配一些新的變量。麻煩的是,每個查詢只有一個用戶最終會擁有通過我的'on_query'方法設置的變量。迭代SQLAlchemy查詢正在重設新分配的變量

...stuff setting up a connection to the database as well as a SQL session. 
    All were done using default values. 

class UserTest(Base): 
    __tablename__ = "testtable" 

    ID = Column(Integer(unsigned=True), 
       primary_key=True, nullable=False, autoincrement=True) 

    def __init__(self): 
     pass 

    def on_query(self): 
     self.foo = "bar" 

query = session.query(UserTest) 

for u in query: 
    u.on_query() 

print [hasattr(u, "foo") for u in query] 
#prints [False, False, False, False, False, False, False, False, False, True] 

session.close() 

我發現,如果我是通過迭代查詢來創建一個列表,在「on_query」的方法將作爲我想要它工作。

users = [u for u in query] 
for u in users: 
    u.on_query() 
print [hasattr(u, "foo") for u in users] 
#prints [True, True, True, True, True, True, True, True, True, True] 

這是什麼原因?有沒有辦法阻止它每次迭代去除'foo'變量?如果可能,我寧願將用戶保留在查詢對象中。

回答

1

在第一種情況下,查詢實際上會產生兩次,一次是for循環,一次是print語句。

由於for循環不斷取代u引用,所以在循環結束時,只有最後一個保留在SQLAlchemy會話中。您可以使用print session.identity_map進行驗證。

當查詢被第二次由print語句產生時,除了最後一個之外的所有數據都必須從數據庫中再次檢索,而最後一個從SQLAlchemy會話直接檢索,因此設置了foo屬性。

編輯:更透明地做到這一點的一種方法是使用重構器,例如,

class UserTest(Base): 
    ... 

    @orm.reconstructor 
    def init_on_load(self): 
     self.foo = "bar"