如果查询不在构造函数中,为什么 Sqlalchemy 会清理查询结果?

问题描述 投票:0回答:1

我创建了一个类

Result
,它接受 sqlalchemy 语句、存储该语句、执行该语句并存储执行结果。

如果直接在

__init__()
中执行该语句,下面的脚本将产生预期的结果:

1  Test JE 1
2  Test JE 2

但是如果该语句在

set_result()
中执行,下面的脚本将输出
No results.
使用
pdb
显示
_cleanup()
set_result()
之后调用:

--Call--
> /usr/lib/python3/dist-packages/sqlalchemy/orm/state.py(420)_cleanup()

为什么在

_cleanup()
之后调用
set_result()
而不是在
__init__()
之后调用?

剧本

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import Column, String, Integer, select

Base = declarative_base()

class JournalEntry(Base):
    __tablename__ = 'JournalEntry'

    pid = Column(Integer, primary_key=True)
    desc = Column(String, nullable=False)

    def __repr__(self):
        return f"{self.pid}  {self.desc}"

class db:
    engine = create_engine('sqlite:///:memory:', echo=False)
    Base.metadata.create_all(engine)
    Session = sessionmaker(engine)

class Result:
    """Helper for printing query results."""
    def __init__(self, stmt):
        self.stmt = stmt
        with db.Session() as session:
            self.result = session.scalars(self.stmt).all()
        #self.result = self.set_result()

    def set_result(self):
        with db.Session() as session:
            self.result = session.scalars(self.stmt).all()
        breakpoint()
        # objects in self.result get cleaned

    def __repr__(self):
        try:
            resultstr = ""
            for obj in self.result:
                resultstr += f"{obj}\n"
            return resultstr
        except TypeError:
            return "No results."

if __name__ == '__main__':
    je1 = JournalEntry(desc="Test JE 1")
    je2 = JournalEntry(desc="Test JE 2")

    with db.Session.begin() as session:
        session.add_all([je1, je2])

    gj = Result(select(JournalEntry))
    print(gj)

python-3.x sqlalchemy
1个回答
0
投票

哈哈,我不小心将

self.result
分配给了“无”。这就是为什么
_cleanup()
被称为。

class Result:
    """Helper for printing query results."""
    def __init__(self, stmt):
        self.stmt = stmt
        self.result = self.set_result()  # <-- self.set_result returns None.
        # Above line should be: self.set_result()

    def set_result(self):
        with db.Session() as session:
            self.result = session.scalars(self.stmt).all()

© www.soinside.com 2019 - 2024. All rights reserved.