From 8532c605fa880f6e144d9039926bb93b3f11d712 Mon Sep 17 00:00:00 2001 From: foefl Date: Thu, 4 Jun 2026 16:42:21 +0200 Subject: [PATCH] prepare database interaction --- prototypes/01_first-look_20260603.py | 35 +++++++++++++++++++++ prototypes/02_save_to_db.py | 27 ++++++++++++++++ src/wattanalyse/db.py | 46 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 prototypes/02_save_to_db.py create mode 100644 src/wattanalyse/db.py diff --git a/prototypes/01_first-look_20260603.py b/prototypes/01_first-look_20260603.py index de4be19..b7591cb 100644 --- a/prototypes/01_first-look_20260603.py +++ b/prototypes/01_first-look_20260603.py @@ -1,9 +1,14 @@ # %% import datetime import enum +import json from pathlib import Path +from typing import Any import polars as pl +import sqlalchemy as sql + +from wattanalyse import db # %% PROJECT_BASE = Path(__file__).parents[1] @@ -408,6 +413,36 @@ tmp = tmp.with_columns( .alias("Durchlaufzeit_Anzahl_Tage"), ) tmp + + +# %% +# // dump to database + + +def _parse_to_json(value: Any) -> str: + if isinstance(value, (datetime.date, datetime.datetime)): + return value.isoformat() + else: + raise TypeError + + +parsed_lists = tmp.with_columns( + pl.col(pl.List) + .map_elements( + lambda x: json.dumps(x.to_list(), default=_parse_to_json) if x is not None else None, + return_dtype=pl.String, + ) + .name.keep() +) +parsed_lists + + +# %% +parsed_lists["Import-Ist_Historie"].item(0) + +# TODO make UPSERT with staging + +######################################################## # %% tmp_1 = tmp.select("Meldezeitpunkt_Historie") tmp_1 = tmp_1.with_columns( diff --git a/prototypes/02_save_to_db.py b/prototypes/02_save_to_db.py new file mode 100644 index 0000000..ba8c6ff --- /dev/null +++ b/prototypes/02_save_to_db.py @@ -0,0 +1,27 @@ +# %% +import datetime +import json +from typing import Any + +# %% +dt = datetime.datetime.now() +date = dt.date() + +# %% +val = [dt, date] +json.dumps(val) + + +# %% +def _parse_to_json(value: Any) -> str: + if isinstance(value, datetime.date): + return value.isoformat() + elif isinstance(value, datetime.datetime): + return value.isoformat() + else: + raise TypeError + + +# %% +json.dumps(val, default=_parse_to_json) +# %% diff --git a/src/wattanalyse/db.py b/src/wattanalyse/db.py new file mode 100644 index 0000000..aa27640 --- /dev/null +++ b/src/wattanalyse/db.py @@ -0,0 +1,46 @@ +import sqlalchemy as sql +from sqlalchemy import Column, Table + +from wattanalyse import constants + +assert constants.Config.DB_PATH_INTERNAL.parent.exists(), ( + "database parent folder does not exists" +) + +ENGINE = sql.create_engine(f"sqlite:///{constants.Config.DB_PATH_INTERNAL}") + +MD_INTERNAL = sql.MetaData() + + +intern_prod_order_t: Table = Table( + "Produktionsauftrag-Einzelsicht", + MD_INTERNAL, + Column("PA", sql.Integer, primary_key=True), + Column("PA_Pos", sql.Integer, primary_key=True), + Column("Konfektionär", sql.Text, nullable=False), + Column("Meldezeitpunkt_Historie", sql.Text, nullable=False), + Column("Liefertermin_Soll", sql.Date, nullable=False), + Column("Bestaetigter-Import_Historie", sql.Text, nullable=False), + Column("Liefertermin_Ist", sql.Date, nullable=True), + Column("Import-Ist_Historie", sql.Text, nullable=False), + Column("Import-Ist_letzter_Wert", sql.Date, nullable=True), + Column("Import-Ist_geaendert", sql.Boolean, nullable=False), + Column("Import-Ist_Anzahl_Aenderungen", sql.Integer, nullable=False), + Column("Tage_zu_letzter_PSM_Historie", sql.Text, nullable=False), + Column("Tage_zu_letzter_PSM_Durchschnitt", sql.Float, nullable=True), + Column("Prod-EP10_Historie", sql.Text, nullable=False), + Column("Prod-EP20_Historie", sql.Text, nullable=False), + Column("Prod-EP30_Historie", sql.Text, nullable=False), + Column("Prod-EP40_Historie", sql.Text, nullable=False), + Column("Prod-EP50_Historie", sql.Text, nullable=False), + Column("Prod-Qualitaet_Historie", sql.Text, nullable=False), + Column("Prod-Qualitaet_Durchschnitt", sql.Float, nullable=False), + Column("Prod-Start_Historie", sql.Text, nullable=False), + Column("Prod-Start", sql.Date, nullable=True), + Column("Terminabweichung_Anzahl_Tage", sql.Integer, nullable=True), + Column("Terminunterschreitung", sql.Boolean, nullable=True), + Column("Terminüberschreitung", sql.Boolean, nullable=True), + Column("Durchlaufzeit_Anzahl_Tage", sql.Float, nullable=True), +) + +MD_INTERNAL.create_all(ENGINE)