Introduces categorizer that works on ORM classes
Categorizer will work directly on ORM classes, which will cleanup the code, since changes will automatically be persisted when change the objects. Adds wrapper session class inside the DbClient for the manager to use. The manager will have to have some DB session knowledge, which adds some unfortunate coupling. Removes some unnecessary relations between tables that were added by mistake. category CLI option now uses the manager.
This commit is contained in:
parent
78e545589d
commit
8fe0ecc597
@ -112,7 +112,7 @@ def argparser(manager: Manager) -> argparse.ArgumentParser:
|
|||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||||
)
|
)
|
||||||
p_categorize.set_defaults(
|
p_categorize.set_defaults(
|
||||||
func=lambda args: categorize_data(DatabaseClient(args.database))
|
func=lambda args: manager.categorize(vars(args))
|
||||||
)
|
)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from pfbudget.input.input import Input
|
from pfbudget.input.input import Input
|
||||||
from pfbudget.input.parsers import parse_data
|
from pfbudget.input.parsers import parse_data
|
||||||
from pfbudget.db.client import DbClient
|
from pfbudget.db.client import DbClient
|
||||||
|
from pfbudget.core.categorizer import Categorizer
|
||||||
from pfbudget.utils import convert
|
from pfbudget.utils import convert
|
||||||
|
|
||||||
|
|
||||||
@ -38,6 +39,12 @@ class Manager:
|
|||||||
session.add(transactions)
|
session.add(transactions)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
def categorize(self, args: dict):
|
||||||
|
with self.db.session() as session:
|
||||||
|
uncategorized = session.uncategorized()
|
||||||
|
Categorizer().categorize(uncategorized)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
# def get_bank_by(self, key: str, value: str) -> Bank:
|
# def get_bank_by(self, key: str, value: str) -> Bank:
|
||||||
# client = DatabaseClient(self.__db)
|
# client = DatabaseClient(self.__db)
|
||||||
# bank = client.get_bank(key, value)
|
# bank = client.get_bank(key, value)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from sqlalchemy import create_engine, select
|
from sqlalchemy import create_engine, select
|
||||||
from sqlalchemy.orm import Session, joinedload, selectinload
|
from sqlalchemy.orm import Session, joinedload, selectinload
|
||||||
|
|
||||||
from pfbudget.db.model import Bank, Transaction
|
from pfbudget.db.model import Bank, Category, Transaction
|
||||||
|
|
||||||
# import logging
|
# import logging
|
||||||
|
|
||||||
@ -55,3 +55,30 @@ class DbClient:
|
|||||||
@property
|
@property
|
||||||
def engine(self):
|
def engine(self):
|
||||||
return self._engine
|
return self._engine
|
||||||
|
|
||||||
|
class ClientSession:
|
||||||
|
def __init__(self, engine):
|
||||||
|
self.__engine = engine
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.__session = Session(self.__engine)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||||
|
self.__session.close()
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
self.__session.commit()
|
||||||
|
|
||||||
|
def add(self, transactions: list[Transaction]):
|
||||||
|
self.__session.add_all(transactions)
|
||||||
|
|
||||||
|
def addcategory(self, category: Category):
|
||||||
|
self.__session.add(category)
|
||||||
|
|
||||||
|
def uncategorized(self) -> list[Transaction]:
|
||||||
|
stmt = select(Transaction).where(~Transaction.category.has())
|
||||||
|
return self.__session.scalars(stmt).all()
|
||||||
|
|
||||||
|
def session(self):
|
||||||
|
return self.ClientSession(self.engine)
|
||||||
|
|||||||
@ -105,9 +105,8 @@ class Category(Base):
|
|||||||
group: Mapped[Optional[str]] = mapped_column(ForeignKey(CategoryGroup.name))
|
group: Mapped[Optional[str]] = mapped_column(ForeignKey(CategoryGroup.name))
|
||||||
|
|
||||||
rules: Mapped[Optional[set[CategoryRule]]] = relationship(
|
rules: Mapped[Optional[set[CategoryRule]]] = relationship(
|
||||||
back_populates="category", cascade="all, delete-orphan", passive_deletes=True
|
cascade="all, delete-orphan", passive_deletes=True
|
||||||
)
|
)
|
||||||
categorygroup: Mapped[Optional[CategoryGroup]] = relationship()
|
|
||||||
|
|
||||||
|
|
||||||
class TransactionCategory(Base):
|
class TransactionCategory(Base):
|
||||||
@ -117,7 +116,6 @@ class TransactionCategory(Base):
|
|||||||
name: Mapped[str] = mapped_column(ForeignKey(Category.name))
|
name: Mapped[str] = mapped_column(ForeignKey(Category.name))
|
||||||
|
|
||||||
original: Mapped[Transaction] = relationship(back_populates="category")
|
original: Mapped[Transaction] = relationship(back_populates="category")
|
||||||
category: Mapped[Category] = relationship()
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Category({self.name})"
|
return f"Category({self.name})"
|
||||||
@ -162,5 +160,3 @@ class CategoryRule(Base):
|
|||||||
ForeignKey(Category.name, ondelete="CASCADE"), primary_key=True
|
ForeignKey(Category.name, ondelete="CASCADE"), primary_key=True
|
||||||
)
|
)
|
||||||
rule: Mapped[str] = mapped_column(primary_key=True)
|
rule: Mapped[str] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
category: Mapped[Category] = relationship(back_populates="rules")
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user