aboutsummaryrefslogtreecommitdiffstats
path: root/python/report_ops/wires.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/report_ops/wires.py')
-rw-r--r--python/report_ops/wires.py55
1 files changed, 46 insertions, 9 deletions
diff --git a/python/report_ops/wires.py b/python/report_ops/wires.py
index 094ae967..13834410 100644
--- a/python/report_ops/wires.py
+++ b/python/report_ops/wires.py
@@ -2,20 +2,44 @@ import datetime
from csv import DictReader
from typing import ClassVar
from functools import partial
-from dataclasses import dataclass, field
+from dataclasses import dataclass, field, Field
import pandas as pd
-from serenitas.ops.trade_dataclasses import Deal, Ccy
+from serenitas.ops.trade_dataclasses import Ccy
from serenitas.ops.dataclass_mapping import Fund
from serenitas.analytics.dates import prev_business_day
from serenitas.analytics.exceptions import MissingDataError
from serenitas.utils.env import DAILY_DIR
+from serenitas.utils.db2 import dbconn
from .misc import get_dir, dt_from_fname, Custodian
+class Report:
+ _sql_insert: ClassVar[str]
+ _insert_queue: ClassVar[list]
+ _insert_fields: ClassVar[list]
+ _conn: ClassVar = dbconn("dawndb")
+ _registry = {}
+
+ def __init_subclass__(cls, table_name: str):
+ cls._insert_fields = list(filter(cls.is_insert_field, cls.__annotations__))
+ place_holders = ",".join(["%s"] * len(cls._insert_fields))
+ cls._sql_insert = f"INSERT INTO {table_name}({','.join(cls._insert_fields)}) VALUES({place_holders}) ON CONFLICT (unique_ref) DO NOTHING RETURNING *"
+ cls._insert_queue = []
+
+ @classmethod
+ def is_insert_field(cls, attr):
+ """fields are insertable by default unless specified otherwise"""
+ match getattr(cls, attr, None):
+ case Field(metadata={"insert": False}) | Field(init=False):
+ return False
+ case _:
+ return True
+
+
@dataclass
-class WireReport(Deal, table_name="custodian_wires", deal_type="custodian_wires"):
+class WireReport(Report, table_name="custodian_wires"):
date: datetime.date
fund: Fund
custodian: ClassVar[Custodian]
@@ -26,17 +50,16 @@ class WireReport(Deal, table_name="custodian_wires", deal_type="custodian_wires"
amount: float
wire_details: str
unique_ref: str
- dtkey: ClassVar = field(metadata={"insert": False, "select": False})
+ dtkey: ClassVar = field(metadata={"insert": False})
def __init_subclass__(cls, custodian, dtkey, **kwargs):
- cls._sql_insert = (
- cls._sql_insert.removesuffix("RETURNING *")
- + "ON CONFLICT (unique_ref) DO NOTHING RETURNING *"
- )
cls.custodian = custodian
cls._registry[custodian] = cls
cls.dtkey = dtkey
+ def __class_getitem__(cls, custodian):
+ return cls._registry[custodian]
+
def __post_init__(self):
if isinstance(self.amount, str):
self.amount = self.amount.replace(",", "")
@@ -45,6 +68,11 @@ class WireReport(Deal, table_name="custodian_wires", deal_type="custodian_wires"
else:
self.amount = float(self.amount)
+ def stage(self):
+ self._insert_queue.append(
+ tuple([getattr(self, col) for col in self._insert_fields])
+ )
+
@classmethod
def get_report(cls, date, fund, prefix=None):
report_dir = get_dir(date)
@@ -62,9 +90,18 @@ class WireReport(Deal, table_name="custodian_wires", deal_type="custodian_wires"
return p
@classmethod
+ def commit(cls):
+ conn = cls._conn
+ with conn.cursor() as c:
+ c.executemany(cls._sql_insert, cls._insert_queue)
+ conn.commit()
+ cls._insert_queue.clear()
+
+ @classmethod
def to_db(cls, date, fund):
for line in cls.yield_rows(date, fund):
- cls.from_report_line(line | {"fund": fund}).stage()
+ trade = cls.from_report_line(line | {"fund": fund})
+ trade.stage()
cls.commit()