0

SQLAlchemy を使用して MySQL データベースに接続しています。今まではうまくいっていたのですが、ちょっと困ったことがあります。いくつかの新しい変数を割り当てるクエリが実行された後、クラスの 1 つでメソッドを呼び出したいと思いました。問題は、クエリごとに 1 人のユーザーだけが、'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」変数を削除するのを止める方法はありますか? 可能であれば、ユーザーをクエリ オブジェクト内に保持したいと思います。

4

1 に答える 1

1

最初のケースでは、クエリは実際には 2 回 (for ループによって 1 回、print ステートメントによって 1 回) 生成されます。

for ループは参照を置き換え続けるため、uループの最後では、最後の 1 つだけが SQLAlchemy セッションに残ります。これは で確認できますprint session.identity_map

クエリが print ステートメントによって 2 回目に生成されると、最後のクエリを除くすべてをデータベースから再度取得する必要がありますが、最後のクエリは SQLAlchemy セッションから直接取得されるため、foo属性が設定されます。

編集:これをより透過的に行う1つの方法は、再構成子を使用することです。

class UserTest(Base):
    ...

    @orm.reconstructor
    def init_on_load(self):
        self.foo = "bar"
于 2012-07-16T01:11:07.603 に答える