From 13e3ef58759bfc69dd9586e3a25f6f7c508dc303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Thu, 9 Mar 2023 07:21:01 +0800 Subject: [PATCH] Replaced querying the accounts later with the "selectinload" query option in the journal and search reports, and restored the lazy setting in the account relationship of the JournalEntry data model. --- src/accounting/models.py | 2 +- src/accounting/report/reports/journal.py | 9 ++- src/accounting/report/reports/search.py | 4 +- tests/testlib_txn.py | 80 ++++++++++++------------ 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/accounting/models.py b/src/accounting/models.py index 9eb1d5e..693c7f6 100644 --- a/src/accounting/models.py +++ b/src/accounting/models.py @@ -617,7 +617,7 @@ class JournalEntry(db.Model): onupdate="CASCADE"), nullable=False) """The account ID.""" - account = db.relationship(Account, back_populates="entries") + account = db.relationship(Account, back_populates="entries", lazy=False) """The account.""" summary = db.Column(db.String, nullable=True) """The summary.""" diff --git a/src/accounting/report/reports/journal.py b/src/accounting/report/reports/journal.py index b3b6faa..f7cc658 100644 --- a/src/accounting/report/reports/journal.py +++ b/src/accounting/report/reports/journal.py @@ -22,6 +22,7 @@ from decimal import Decimal import sqlalchemy as sa from flask import render_template, Response +from sqlalchemy.orm import selectinload from accounting import db from accounting.locale import gettext @@ -64,6 +65,7 @@ class ReportEntry: """The amount.""" if entry is not None: self.entry = entry + self.account = entry.account self.summary = entry.summary self.debit = entry.amount if entry.is_debit else None self.credit = None if entry.is_debit else entry.amount @@ -161,15 +163,11 @@ def populate_entries(entries: list[ReportEntry]) -> None: transactions: dict[int, Transaction] \ = {x.id: x for x in Transaction.query.filter( Transaction.id.in_({x.entry.transaction_id for x in entries}))} - accounts: dict[int, Account] \ - = {x.id: x for x in Account.query.filter( - Account.id.in_({x.entry.account_id for x in entries}))} currencies: dict[int, Currency] \ = {x.code: x for x in Currency.query.filter( Currency.code.in_({x.entry.currency_code for x in entries}))} for entry in entries: entry.transaction = transactions[entry.entry.transaction_id] - entry.account = accounts[entry.entry.account_id] entry.currency = currencies[entry.entry.currency_code] @@ -218,7 +216,8 @@ class Journal(BaseReport): .query(JournalEntry).join(Transaction).filter(*conditions) .order_by(Transaction.date, JournalEntry.is_debit.desc(), - JournalEntry.no).all()] + JournalEntry.no) + .options(selectinload(JournalEntry.account)).all()] def csv(self) -> Response: """Returns the report as CSV for download. diff --git a/src/accounting/report/reports/search.py b/src/accounting/report/reports/search.py index e5a45fc..44f76fe 100644 --- a/src/accounting/report/reports/search.py +++ b/src/accounting/report/reports/search.py @@ -22,6 +22,7 @@ from decimal import Decimal import sqlalchemy as sa from flask import Response, render_template, request +from sqlalchemy.orm import selectinload from accounting.locale import gettext from accounting.models import Currency, CurrencyL10n, Account, AccountL10n, \ @@ -67,7 +68,8 @@ class EntryCollector: except ArithmeticError: pass conditions.append(sa.or_(*sub_conditions)) - return [ReportEntry(x) for x in JournalEntry.query.filter(*conditions)] + return [ReportEntry(x) for x in JournalEntry.query.filter(*conditions) + .options(selectinload(JournalEntry.account))] @staticmethod def __get_account_condition(k: str) -> sa.Select: diff --git a/tests/testlib_txn.py b/tests/testlib_txn.py index f327487..da675d2 100644 --- a/tests/testlib_txn.py +++ b/tests/testlib_txn.py @@ -137,48 +137,48 @@ def get_unchanged_update_form(txn_id: int, app: Flask, csrf_token: str) \ assert txn is not None currencies: list[TransactionCurrency] = txn.currencies - form: dict[str, str] = {"csrf_token": csrf_token, - "next": NEXT_URI, - "date": txn.date, - "note": " \n \n\n " if txn.note is None - else f"\n \n\n \n \n{txn.note} \n\n "} - currency_indices_used: set[int] = set() - currency_no: int = 0 - for currency in currencies: - currency_index: int = __get_new_index(currency_indices_used) - currency_no = currency_no + 3 + randbelow(3) - currency_prefix: str = f"currency-{currency_index}" - form[f"{currency_prefix}-no"] = str(currency_no) - form[f"{currency_prefix}-code"] = currency.code - entry_indices_used: set[int] - entry_no: int - prefix: str + form: dict[str, str] = {"csrf_token": csrf_token, + "next": NEXT_URI, + "date": txn.date, + "note": " \n \n\n " if txn.note is None + else f"\n \n\n \n \n{txn.note} \n\n "} + currency_indices_used: set[int] = set() + currency_no: int = 0 + for currency in currencies: + currency_index: int = __get_new_index(currency_indices_used) + currency_no = currency_no + 3 + randbelow(3) + currency_prefix: str = f"currency-{currency_index}" + form[f"{currency_prefix}-no"] = str(currency_no) + form[f"{currency_prefix}-code"] = currency.code + entry_indices_used: set[int] + entry_no: int + prefix: str - entry_indices_used = set() - entry_no = 0 - for entry in currency.debit: - entry_index: int = __get_new_index(entry_indices_used) - entry_no = entry_no + 3 + randbelow(3) - prefix = f"{currency_prefix}-debit-{entry_index}" - form[f"{prefix}-eid"] = str(entry.id) - form[f"{prefix}-no"] = str(entry_no) - form[f"{prefix}-account_code"] = entry.account.code - form[f"{prefix}-summary"] \ - = " " if entry.summary is None else f" {entry.summary} " - form[f"{prefix}-amount"] = str(entry.amount) + entry_indices_used = set() + entry_no = 0 + for entry in currency.debit: + entry_index: int = __get_new_index(entry_indices_used) + entry_no = entry_no + 3 + randbelow(3) + prefix = f"{currency_prefix}-debit-{entry_index}" + form[f"{prefix}-eid"] = str(entry.id) + form[f"{prefix}-no"] = str(entry_no) + form[f"{prefix}-account_code"] = entry.account.code + form[f"{prefix}-summary"] \ + = " " if entry.summary is None else f" {entry.summary} " + form[f"{prefix}-amount"] = str(entry.amount) - entry_indices_used = set() - entry_no = 0 - for entry in currency.credit: - entry_index: int = __get_new_index(entry_indices_used) - entry_no = entry_no + 3 + randbelow(3) - prefix = f"{currency_prefix}-credit-{entry_index}" - form[f"{prefix}-eid"] = str(entry.id) - form[f"{prefix}-no"] = str(entry_no) - form[f"{prefix}-account_code"] = entry.account.code - form[f"{prefix}-summary"] \ - = " " if entry.summary is None else f" {entry.summary} " - form[f"{prefix}-amount"] = str(entry.amount) + entry_indices_used = set() + entry_no = 0 + for entry in currency.credit: + entry_index: int = __get_new_index(entry_indices_used) + entry_no = entry_no + 3 + randbelow(3) + prefix = f"{currency_prefix}-credit-{entry_index}" + form[f"{prefix}-eid"] = str(entry.id) + form[f"{prefix}-no"] = str(entry_no) + form[f"{prefix}-account_code"] = entry.account.code + form[f"{prefix}-summary"] \ + = " " if entry.summary is None else f" {entry.summary} " + form[f"{prefix}-amount"] = str(entry.amount) return form