迭代SQLAlchemy查询正在重置新分配的变量

时间:2012-07-15 20:01:17

标签: python sqlalchemy

我一直在使用SQLAlchemy连接到MySQL数据库。它一直运作良好,但我遇到了一些麻烦。我想在查询之后在我的一个类上调用一个方法,它会分配一些新的变量。问题是每个查询只有一个用户最终会通过我的'on_query'方法设置变量。

...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 个答案:

答案 0 :(得分: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"