Rule inheritance
Both rules, categorries and tags, now derive from the rule base type. This clears up some type definitions.
This commit is contained in:
parent
6110858d48
commit
d4b5f1f11a
152
alembic/versions/6b293f78cc97_rule_inheritance.py
Normal file
152
alembic/versions/6b293f78cc97_rule_inheritance.py
Normal file
@ -0,0 +1,152 @@
|
||||
"""Rule inheritance
|
||||
|
||||
Revision ID: 6b293f78cc97
|
||||
Revises: 37d80de801a7
|
||||
Create Date: 2023-01-22 20:05:32.887092+00:00
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "6b293f78cc97"
|
||||
down_revision = "37d80de801a7"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"rules",
|
||||
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
|
||||
sa.Column("date", sa.Date(), nullable=True),
|
||||
sa.Column("description", sa.String(), nullable=True),
|
||||
sa.Column("regex", sa.String(), nullable=True),
|
||||
sa.Column("bank", sa.String(), nullable=True),
|
||||
sa.Column("min", sa.Numeric(precision=16, scale=2), nullable=True),
|
||||
sa.Column("max", sa.Numeric(precision=16, scale=2), nullable=True),
|
||||
sa.Column("type", sa.String(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_rules")),
|
||||
schema="transactions",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
op.f("fk_categories_rules_id_rules"),
|
||||
"categories_rules",
|
||||
"rules",
|
||||
["id"],
|
||||
["id"],
|
||||
source_schema="transactions",
|
||||
referent_schema="transactions",
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
op.drop_column("categories_rules", "bank", schema="transactions")
|
||||
op.drop_column("categories_rules", "min", schema="transactions")
|
||||
op.drop_column("categories_rules", "date", schema="transactions")
|
||||
op.drop_column("categories_rules", "regex", schema="transactions")
|
||||
op.drop_column("categories_rules", "description", schema="transactions")
|
||||
op.drop_column("categories_rules", "max", schema="transactions")
|
||||
op.create_foreign_key(
|
||||
op.f("fk_tag_rules_id_rules"),
|
||||
"tag_rules",
|
||||
"rules",
|
||||
["id"],
|
||||
["id"],
|
||||
source_schema="transactions",
|
||||
referent_schema="transactions",
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
op.drop_column("tag_rules", "bank", schema="transactions")
|
||||
op.drop_column("tag_rules", "min", schema="transactions")
|
||||
op.drop_column("tag_rules", "date", schema="transactions")
|
||||
op.drop_column("tag_rules", "regex", schema="transactions")
|
||||
op.drop_column("tag_rules", "description", schema="transactions")
|
||||
op.drop_column("tag_rules", "max", schema="transactions")
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column(
|
||||
"max", sa.NUMERIC(precision=16, scale=2), autoincrement=False, nullable=True
|
||||
),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column("description", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column("regex", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column("date", sa.DATE(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column(
|
||||
"min", sa.NUMERIC(precision=16, scale=2), autoincrement=False, nullable=True
|
||||
),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"tag_rules",
|
||||
sa.Column("bank", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.drop_constraint(
|
||||
op.f("fk_tag_rules_id_rules"),
|
||||
"tag_rules",
|
||||
schema="transactions",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column(
|
||||
"max", sa.NUMERIC(precision=16, scale=2), autoincrement=False, nullable=True
|
||||
),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column("description", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column("regex", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column("date", sa.DATE(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column(
|
||||
"min", sa.NUMERIC(precision=16, scale=2), autoincrement=False, nullable=True
|
||||
),
|
||||
schema="transactions",
|
||||
)
|
||||
op.add_column(
|
||||
"categories_rules",
|
||||
sa.Column("bank", sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
schema="transactions",
|
||||
)
|
||||
op.drop_constraint(
|
||||
op.f("fk_categories_rules_id_rules"),
|
||||
"categories_rules",
|
||||
schema="transactions",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.drop_table("rules", schema="transactions")
|
||||
# ### end Alembic commands ###
|
||||
@ -223,8 +223,13 @@ class Manager:
|
||||
case Operation.ImportCategoryRules:
|
||||
rules = [CategoryRule(**row) for row in self.load(params[0])]
|
||||
|
||||
with self.db.session() as session:
|
||||
session.add(rules)
|
||||
if (
|
||||
len(rules) > 0
|
||||
and input(f"{rules[:5]}\nDoes the import seem correct? (y/n)")
|
||||
== "y"
|
||||
):
|
||||
with self.db.session() as session:
|
||||
session.add(rules)
|
||||
|
||||
case Operation.ExportTagRules:
|
||||
with self.db.session() as session:
|
||||
@ -233,8 +238,13 @@ class Manager:
|
||||
case Operation.ImportTagRules:
|
||||
rules = [TagRule(**row) for row in self.load(params[0])]
|
||||
|
||||
with self.db.session() as session:
|
||||
session.add(rules)
|
||||
if (
|
||||
len(rules) > 0
|
||||
and input(f"{rules[:5]}\nDoes the import seem correct? (y/n)")
|
||||
== "y"
|
||||
):
|
||||
with self.db.session() as session:
|
||||
session.add(rules)
|
||||
|
||||
# def init(self):
|
||||
# client = DatabaseClient(self.__db)
|
||||
|
||||
@ -283,7 +283,10 @@ class Link(Base):
|
||||
link: Mapped[idfk] = mapped_column(primary_key=True)
|
||||
|
||||
|
||||
class Rule(Export):
|
||||
class Rule(Base, Export):
|
||||
__tablename__ = "rules"
|
||||
|
||||
id: Mapped[idpk] = mapped_column(init=False)
|
||||
date: Mapped[Optional[dt.date]]
|
||||
description: Mapped[Optional[str]]
|
||||
regex: Mapped[Optional[str]]
|
||||
@ -291,6 +294,13 @@ class Rule(Export):
|
||||
min: Mapped[Optional[money]]
|
||||
max: Mapped[Optional[money]]
|
||||
|
||||
type: Mapped[str] = mapped_column(init=False)
|
||||
|
||||
__mapper_args__ = {
|
||||
"polymorphic_identity": "rule",
|
||||
"polymorphic_on": "type",
|
||||
}
|
||||
|
||||
def matches(self, transaction: BankTransaction) -> bool:
|
||||
if (
|
||||
(self.date and self.date < transaction.date)
|
||||
@ -322,15 +332,25 @@ class Rule(Export):
|
||||
bank=self.bank,
|
||||
min=self.min,
|
||||
max=self.max,
|
||||
type=self.type,
|
||||
)
|
||||
|
||||
|
||||
class CategoryRule(Base, Rule):
|
||||
class CategoryRule(Rule):
|
||||
__tablename__ = "categories_rules"
|
||||
|
||||
id: Mapped[idpk] = mapped_column(init=False)
|
||||
id: Mapped[int] = mapped_column(
|
||||
BigInteger,
|
||||
ForeignKey(Rule.id, ondelete="CASCADE"),
|
||||
primary_key=True,
|
||||
init=False,
|
||||
)
|
||||
name: Mapped[catfk]
|
||||
|
||||
__mapper_args__ = {
|
||||
"polymorphic_identity": "category_rule",
|
||||
}
|
||||
|
||||
@property
|
||||
def format(self) -> dict[str, Any]:
|
||||
return super().format | dict(name=self.name)
|
||||
@ -339,12 +359,21 @@ class CategoryRule(Base, Rule):
|
||||
return hash(self.id)
|
||||
|
||||
|
||||
class TagRule(Base, Rule):
|
||||
class TagRule(Rule):
|
||||
__tablename__ = "tag_rules"
|
||||
|
||||
id: Mapped[idpk] = mapped_column(init=False)
|
||||
id: Mapped[int] = mapped_column(
|
||||
BigInteger,
|
||||
ForeignKey(Rule.id, ondelete="CASCADE"),
|
||||
primary_key=True,
|
||||
init=False,
|
||||
)
|
||||
tag: Mapped[str] = mapped_column(ForeignKey(Tag.name, ondelete="CASCADE"))
|
||||
|
||||
__mapper_args__ = {
|
||||
"polymorphic_identity": "tag_rule",
|
||||
}
|
||||
|
||||
@property
|
||||
def format(self) -> dict[str, Any]:
|
||||
return super().format | dict(tag=self.tag)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user