Compare commits
No commits in common. "8fe0ecc597712a2f220d3f019cecd3805693b041" and "e379d7799551cafa4ad933aeabcc38420e4b7efd" have entirely different histories.
8fe0ecc597
...
e379d77995
@ -1,49 +0,0 @@
|
|||||||
"""Available categories and rules
|
|
||||||
|
|
||||||
Revision ID: 2d0891f1be11
|
|
||||||
Revises: 287fe9e6682a
|
|
||||||
Create Date: 2022-12-04 11:15:22.758487+00:00
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = "2d0891f1be11"
|
|
||||||
down_revision = "287fe9e6682a"
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table(
|
|
||||||
"categories_available",
|
|
||||||
sa.Column("name", sa.String(), nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint("name", name=op.f("pk_categories_available")),
|
|
||||||
schema="transactions",
|
|
||||||
)
|
|
||||||
op.create_table(
|
|
||||||
"categories_rules",
|
|
||||||
sa.Column("name", sa.String(), nullable=False),
|
|
||||||
sa.Column("rule", sa.String(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(
|
|
||||||
["name"],
|
|
||||||
["transactions.categories_available.name"],
|
|
||||||
name=op.f("fk_categories_rules_name_categories_available"),
|
|
||||||
ondelete="CASCADE",
|
|
||||||
),
|
|
||||||
sa.PrimaryKeyConstraint("name", "rule", name=op.f("pk_categories_rules")),
|
|
||||||
schema="transactions",
|
|
||||||
)
|
|
||||||
op.alter_column("categorized", "category", new_column_name="name", schema="transactions")
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.alter_column("categorized", "name", new_column_name="category", schema="transactions")
|
|
||||||
op.drop_table("categories_rules", schema="transactions")
|
|
||||||
op.drop_table("categories_available", schema="transactions")
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
"""Category groups and relationships
|
|
||||||
|
|
||||||
Revision ID: 83f4c9837f6e
|
|
||||||
Revises: 2d0891f1be11
|
|
||||||
Create Date: 2022-12-04 15:10:51.924875+00:00
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = "83f4c9837f6e"
|
|
||||||
down_revision = "2d0891f1be11"
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table(
|
|
||||||
"categories_groups",
|
|
||||||
sa.Column("name", sa.String(), nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint("name", name=op.f("pk_categories_groups")),
|
|
||||||
schema="transactions",
|
|
||||||
)
|
|
||||||
op.add_column(
|
|
||||||
"categories_available",
|
|
||||||
sa.Column("group", sa.String(), nullable=True),
|
|
||||||
schema="transactions",
|
|
||||||
)
|
|
||||||
op.create_foreign_key(
|
|
||||||
op.f("fk_categories_available_group_categories_groups"),
|
|
||||||
"categories_available",
|
|
||||||
"categories_groups",
|
|
||||||
["group"],
|
|
||||||
["name"],
|
|
||||||
source_schema="transactions",
|
|
||||||
referent_schema="transactions",
|
|
||||||
)
|
|
||||||
op.create_foreign_key(
|
|
||||||
op.f("fk_categorized_name_categories_available"),
|
|
||||||
"categorized",
|
|
||||||
"categories_available",
|
|
||||||
["name"],
|
|
||||||
["name"],
|
|
||||||
source_schema="transactions",
|
|
||||||
referent_schema="transactions",
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_constraint(
|
|
||||||
op.f("fk_categorized_name_categories_available"),
|
|
||||||
"categorized",
|
|
||||||
schema="transactions",
|
|
||||||
type_="foreignkey",
|
|
||||||
)
|
|
||||||
op.drop_constraint(
|
|
||||||
op.f("fk_categories_available_group_categories_groups"),
|
|
||||||
"categories_available",
|
|
||||||
schema="transactions",
|
|
||||||
type_="foreignkey",
|
|
||||||
)
|
|
||||||
op.drop_column("categories_available", "group", schema="transactions")
|
|
||||||
op.drop_table("categories_groups", schema="transactions")
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
@ -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: manager.categorize(vars(args))
|
func=lambda args: categorize_data(DatabaseClient(args.database))
|
||||||
)
|
)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
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
|
||||||
|
|
||||||
|
|
||||||
@ -39,12 +38,6 @@ 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, Category, Transaction
|
from pfbudget.db.model import Bank, Transaction
|
||||||
|
|
||||||
# import logging
|
# import logging
|
||||||
|
|
||||||
@ -55,30 +55,3 @@ 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)
|
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class Transaction(Base):
|
|||||||
bank: Mapped[bankfk]
|
bank: Mapped[bankfk]
|
||||||
amount: Mapped[money]
|
amount: Mapped[money]
|
||||||
|
|
||||||
category: Mapped[Optional[TransactionCategory]] = relationship(
|
category: Mapped[Optional[Category]] = relationship(
|
||||||
back_populates="original", lazy="joined"
|
back_populates="original", lazy="joined"
|
||||||
)
|
)
|
||||||
note: Mapped[Optional[Note]] = relationship(back_populates="original")
|
note: Mapped[Optional[Note]] = relationship(back_populates="original")
|
||||||
@ -92,33 +92,16 @@ idfk = Annotated[
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CategoryGroup(Base):
|
|
||||||
__tablename__ = "categories_groups"
|
|
||||||
|
|
||||||
name: Mapped[str] = mapped_column(primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
class Category(Base):
|
class Category(Base):
|
||||||
__tablename__ = "categories_available"
|
|
||||||
|
|
||||||
name: Mapped[str] = mapped_column(primary_key=True)
|
|
||||||
group: Mapped[Optional[str]] = mapped_column(ForeignKey(CategoryGroup.name))
|
|
||||||
|
|
||||||
rules: Mapped[Optional[set[CategoryRule]]] = relationship(
|
|
||||||
cascade="all, delete-orphan", passive_deletes=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TransactionCategory(Base):
|
|
||||||
__tablename__ = "categorized"
|
__tablename__ = "categorized"
|
||||||
|
|
||||||
id: Mapped[idfk] = mapped_column(primary_key=True)
|
id: Mapped[idfk] = mapped_column(primary_key=True)
|
||||||
name: Mapped[str] = mapped_column(ForeignKey(Category.name))
|
category: Mapped[str]
|
||||||
|
|
||||||
original: Mapped[Transaction] = relationship(back_populates="category")
|
original: Mapped[Transaction] = relationship(back_populates="category")
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Category({self.name})"
|
return f"Category({self.category})"
|
||||||
|
|
||||||
|
|
||||||
class Note(Base):
|
class Note(Base):
|
||||||
@ -151,12 +134,3 @@ class Tag(Base):
|
|||||||
tag: Mapped[str] = mapped_column(primary_key=True)
|
tag: Mapped[str] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
original: Mapped[Transaction] = relationship(back_populates="tags")
|
original: Mapped[Transaction] = relationship(back_populates="tags")
|
||||||
|
|
||||||
|
|
||||||
class CategoryRule(Base):
|
|
||||||
__tablename__ = "categories_rules"
|
|
||||||
|
|
||||||
name: Mapped[str] = mapped_column(
|
|
||||||
ForeignKey(Category.name, ondelete="CASCADE"), primary_key=True
|
|
||||||
)
|
|
||||||
rule: Mapped[str] = mapped_column(primary_key=True)
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user