2012-07-15 63 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"