[Fix] Select statement dangling session

The `Client` was never closing the `Session` in `DatabaseSession`, which
meant that tests that compared transactions and banks would work since
attributes loaded only on select would still work.
However, this was not the intended behavior. Calling select from the
client with using sessions should detach objects completely from a DB
session. Therefore, attributes on Transaction, TransactionCategory and
Bank are now loaded on a join (lazy parameter).
This commit is contained in:
Luís Murta 2023-05-08 19:31:08 +01:00
parent 1628f6c1ea
commit 48fae5483d
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
2 changed files with 13 additions and 7 deletions

View File

@ -22,6 +22,9 @@ class DatabaseSession:
self.__session.commit() self.__session.commit()
self.__session.close() self.__session.close()
def close(self):
self.__session.close()
def insert(self, sequence: Sequence[Any]) -> None: def insert(self, sequence: Sequence[Any]) -> None:
self.__session.add_all(sequence) self.__session.add_all(sequence)
@ -33,7 +36,7 @@ class DatabaseSession:
else: else:
stmt = select(what) stmt = select(what)
return self.__session.scalars(stmt).all() return self.__session.scalars(stmt).unique().all()
class Client: class Client:
@ -50,7 +53,10 @@ class Client:
T = TypeVar("T") T = TypeVar("T")
def select(self, what: Type[T], exists: Optional[Any] = None) -> Sequence[T]: def select(self, what: Type[T], exists: Optional[Any] = None) -> Sequence[T]:
return self.session.select(what, exists) session = self.session
result = session.select(what, exists)
session.close()
return result
def update(self, what: Type[Any], values: Sequence[Mapping[str, Any]]) -> None: def update(self, what: Type[Any], values: Sequence[Mapping[str, Any]]) -> None:
with self._sessionmaker() as session, session.begin(): with self._sessionmaker() as session, session.begin():

View File

@ -65,7 +65,7 @@ class Bank(Base, Export):
BIC: Mapped[str] = mapped_column(String(8)) BIC: Mapped[str] = mapped_column(String(8))
type: Mapped[accounttype] type: Mapped[accounttype]
nordigen: Mapped[Optional[Nordigen]] = relationship(init=False) nordigen: Mapped[Optional[Nordigen]] = relationship(init=False, lazy="joined")
@property @property
def format(self) -> dict[str, Any]: def format(self) -> dict[str, Any]:
@ -101,11 +101,11 @@ class Transaction(Base, Export):
split: Mapped[bool] = mapped_column(default=False) split: Mapped[bool] = mapped_column(default=False)
category: Mapped[Optional[TransactionCategory]] = relationship( category: Mapped[Optional[TransactionCategory]] = relationship(
back_populates="transaction", default=None back_populates="transaction", default=None, lazy="joined"
) )
tags: Mapped[set[TransactionTag]] = relationship(default_factory=set) tags: Mapped[set[TransactionTag]] = relationship(default_factory=set, lazy="joined")
note: Mapped[Optional[Note]] = relationship( note: Mapped[Optional[Note]] = relationship(
cascade="all, delete-orphan", passive_deletes=True, default=None cascade="all, delete-orphan", passive_deletes=True, default=None, lazy="joined"
) )
type: Mapped[str] = mapped_column(init=False) type: Mapped[str] = mapped_column(init=False)
@ -221,7 +221,7 @@ class TransactionCategory(Base, Export):
name: Mapped[catfk] name: Mapped[catfk]
selector: Mapped[CategorySelector] = relationship( selector: Mapped[CategorySelector] = relationship(
cascade="all, delete-orphan", default=Selector_T.unknown cascade="all, delete-orphan", default=Selector_T.unknown, lazy="joined"
) )
transaction: Mapped[Transaction] = relationship( transaction: Mapped[Transaction] = relationship(