Wäre es nicht interessant den eigenen Kontostand zu beobachten? Somit zu erfahren, ob wirklich Geld im Monat übrig bleibt oder zu viel ausgegeben wurde? Diese Idee kam mir vor einiger Zeit. In der Banking-App sehe ich nur den Verlauf meiner Ausgaben und Einnahmen. Allerdings nicht, ob am Ende eines Monats Geld übrig geblieben ist. Erschwerend kommt noch hinzu, dass ich viel mit dem Geld jongliere und auf mehrere Konten verteile. Das führt dazu, dass die grafischen Anzeigen der Bank wirres Zeug anzeigen. Um diesen Problem Herr zu werden, habe ich es mir zur Aufgabe gemacht, jeden Monat zum 1. meine Salden abzufragen. Die Ergebnisse tragen ich dann in eine Datenbank-Tabelle ein.
Da das eigene Einkommen auch mit dazu beiträgt, habe ich es ebenfalls mit ins Projekt reingenommen.
Datenbank Design
In der Datenbank, ich nenne sie Balance, gibt es insgesamt 6 Tabellen, mehrere Unique Key, Primary Key, Foreign Keys und Triggers. In BAL_BANKACCOUNT, BAL_COMPANY, BAL_LOCATION, BAL_INSTITUTION werden Stammdaten eingetragen und dienen als Fremdschlüssel für andere Tabellen. BAL_INCOME und BAL_BALANCE enthalten die gewünschten Informationen, die später ausgelesen werden.
Eigentlich wollte ich z.B. in BAL_INCOME einen Primärschlüssel aus COMPANY_ID, MONTH und YEAR, um so Doppeleinträge zu verhindern. Leider sorgt Django zu einer Limitierung und ich habe ID als primären Schlüssel definieren müssen. Von Django möchte ich das Admin-Interface benutzen, wie ich es auch schon zuvor getan habe. Django erfordert genau einen Primärschlüssel und ein Verbund aus Primärschlüsseln sorgt für Fehler, daher ist ID der alleinige Primärschlüssel und MONTH, YEAR und BNR sind als unique deklariert worden.
BAL_BANKACCOUNT | Alle Bank Konten werden hier eingetragen |
BAL_COMPANY | Alle Firmen werden hier eingetragen |
BAL_LOCATION | Alle Orte werden hier eingetragen |
BAL_INSTITUTION | Alle Bank Institutionen werden hier eingetragen |
BAL_INCOME | Das Einkommen wird hier eingetragen |
BAL_BALANCE | Die Salden werden hier eingetragen |
Eine Sache muss hier aber noch erwähnt werden und das ist die Prozedur. Würde ich jetzt eine Result von BAL_BALANCE zurückbekommen, so wären die Bankkonten im Result aufzufinden.
ID | MONTH | YEAR | BNR | BALANCE | A.._BALANCE | U.._BALANCE |
1 | 1 | 2021 | Konto1 | 3000 | 3000 | 0 |
2 | 1 | 2021 | Konto2 | 20000 | 15000 | 5000 |
3 | 1 | 2021 | Konto3 | 10000 | 10000 | 0 |
4 | 1 | 2021 | Konto4 | 50000 | 50000 | 0 |
5 | 2 | 2021 | Konto1 | 3500 | 3500 | 0 |
… | … | … | … | … | … | … |
Zur Weiterverarbeitung mit Pandas wollte ich diese allerdings als Spaltennamen einsetzen. Zusätzlich wollte ich es vermeiden, immer und immer wieder neue Bankkonten als neue Spalte hinzufügen zu müssen.
CREATE DEFINER=`username`@`%` PROCEDURE `P_BAL_BALANCE`(IN START int, IN END int) BEGIN SELECT GROUP_CONCAT(DISTINCT CONCAT( 'ifnull(SUM(case when BNR = ''', BNR, ''' then BALANCE end),0) AS `', BNR, '`' ) ) INTO @sql FROM Balance.BAL_BALANCE ; SET @sql = CONCAT('SELECT YEAR,MONTH, ', @sql, ' FROM Balance.BAL_BALANCE where YEAR >= ', START ,' and YEAR <= ', END ,' GROUP BY YEAR,MONTH'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END
Die Prozedur nimmt sich die BNRs und verwendet diese als Spaltennamen und erwartet zusätzlich noch ein Start- sowie Endjahr, von dem es die Results bereitstellen soll. Der Aufruf ist dahingehend einfach:
call Balance.P_BAL_BALANCE(2019, 2021);
MONTH | YEAR | KONTO1 | KONTO2 | KONTO3 | KONTO4 |
… | … | … | … | … | … |
1 | 2021 | 3000 | 20000 | 10000 | 50000 |
2 | 2021 | 3500 | … | … | … |
… | … | … | … | … | … |
Noch zu erwähnen wäre der Trigger in BAL_INCOME, denn der berechnet die gesetzlichen Abgaben anhand der Daten, die eingegeben worden sind.
CREATE DEFINER=`username`@`%` TRIGGER `Balance`.`BAL_INCOME_BEFORE_INSERT` BEFORE INSERT ON `BAL_INCOME` FOR EACH ROW BEGIN set NEW.STATUTORY_LEVIES = NEW.INCOME - NEW.NET_INCOME; END
Kontostand in Python Dash
Die Erstellung des Backends ist somit erledigt. Den Kontostand und somit die Visualisierung stelle ich mit Plotly/Dash grafisch her. Es würde den Rahmen sprengen den kompletten Code hier zu veröffentlichen, daher habe ich ihn auf github hochgeladen. Wer daran interessiert ist, findet ihn hier: https://github.com/stevieWoW/balance.