Ist die Programmierung dieser Klasse in Ordnung?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Soooo,
ich habe endlich mal etwas Durchblick in der Doc bekommen :D .

Mache es nach dem neuen Prinzip.
Hier meine Mapper Klassen:
Habe jetzt auch einen Fremdschlüssel eingefügt.

Code: Alles auswählen

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Relationship, Mapped, mapped_column
from typing import List, Optional

engine = create_engine('sqlite:///Datenbank/verbrauch.db')


class Base(DeclarativeBase):
    pass


class Vertragsdaten(Base):
    __tablename__ = 'vertragsdaten'

    vertragsdaten_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    versorger: Mapped[Optional[str]]
    vertragsbeginn: Mapped[Optional[str]]
    tarif: Mapped[List["Tarif"]] = Relationship(back_populates="vertragsdaten")


class Tarif(Base):
    __tablename__ = 'tarif'

    tarif_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    arbeitspreis: Mapped[Optional[float]]
    grundpreis: Mapped[Optional[float]]
    mehrwertsteuer: Mapped[Optional[float]]
    zaehlerstand_letzte_abrechnung: Mapped[Optional[float]]
    monatlicher_abschlag: Mapped[Optional[float]]
    vertragsdaten_id: Mapped[int] = mapped_column(ForeignKey("vertragsdaten.vertragsdaten_id"))
    vertragsdaten: Mapped["Vertragsdaten"] = Relationship(back_populates="tarif")
Hier Abrechnung mit der @classmethod

Code: Alles auswählen

class Abrechnung:
    """ Klasse Abrechnung. Hier befinden sich die Methoden zur Berechnung der Verbrauchsdaten"""

    def __init__(self, eingegebener_zaehlerstand, zaehlerstand_letzte_abrechnung, arbeitspreis, grundpreis,
                 mehrwertsteuer, monatlicher_abschlag):
        self.eingegebener_zaehlerstand = eingegebener_zaehlerstand
        self.zaehlerstand_letzte_abrechnung = zaehlerstand_letzte_abrechnung
        self.arbeitspreis = arbeitspreis
        self.grundpreis = grundpreis
        self.mehrwertsteuer = mehrwertsteuer
        self.monatlicher_abschlag = monatlicher_abschlag

    @classmethod
    def from_database(cls, eingegebener_zaehlerstand):
        with Session(engine) as session:
            tarif = session.get(Tarif, 1)
            return cls(eingegebener_zaehlerstand, tarif.zaehlerstand_letzte_abrechnung, tarif.arbeitspreis,
                       tarif.grundpreis, tarif.mehrwertsteuer, tarif.monatlicher_abschlag)
@snafu
Da würde man besser das Tarif-Objekt als Ganzes übergeben und dann innerhalb der Abrechnung auf die benötigten Attribute zugreifen.
OK, hört sich interessant an. Ich mache mir mal Gedanken wie dies gehen könnte. Vielleicht komme ich ja drauf :wink:
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Hallo,
mhh ich weiß nicht ob es so gut ist. Ich hatte, glaube ich, etwas in der SQLAlchemy Doc gelesen das man eine Mapper Klasse direkt initialisieren kann, finde es leider aber nicht mehr. Aber ich meine auch, dass dies aber dann nur mit einer Klasse, sprich mit einer Tabelle, ginge. Und das ist ja auch keine Lösung.

Aber ich konnte mir noch vorstellen, dass man das Tarifobjekt auf die Modul Ebene setzten kann. Darum habe ich ein Sesson Objekt in einer with Anweisung und das Tarif Objekt auf die Modul Ebene gesetzt. Bleibt jetzt nur die Frage ob man dies so lassen kann?

Ich stelle mal alle meine Klassen wo ich jetzt etwas geändert habe rein, und wenn ihr Zeit und Lust habt könnt ihr ja mal drüber sehen.

Danke schon mal und Grüße Master_Shredder

Datenbankverbindung.py:

Code: Alles auswählen

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Relationship, Mapped, mapped_column
from typing import List, Optional

engine = create_engine('sqlite:///Datenbank/verbrauchsrechner.db')


class Base(DeclarativeBase):
    pass


class Vertragsdaten(Base):
    __tablename__ = 'vertragsdaten'

    vertragsdaten_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    versorger: Mapped[Optional[str]]
    vertragsbeginn: Mapped[Optional[str]]
    tarif: Mapped[List["Tarif"]] = Relationship(back_populates="vertragsdaten")


class Tarif(Base):
    __tablename__ = 'tarif'

    tarif_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    arbeitspreis: Mapped[Optional[float]]
    grundpreis: Mapped[Optional[float]]
    mehrwertsteuer: Mapped[Optional[float]]
    zaehlerstand_letzte_abrechnung: Mapped[Optional[float]]
    monatlicher_abschlag: Mapped[Optional[float]]
    vertragsdaten_id: Mapped[int] = mapped_column(ForeignKey("vertragsdaten.vertragsdaten_id"))
    vertragsdaten: Mapped["Vertragsdaten"] = Relationship(back_populates="tarif")
Abrechnung.py:

Code: Alles auswählen

import math
from datetime import datetime
from sqlalchemy.orm import Session
from Datenbank.Datenbankverbindung import Tarif, engine

with Session(engine) as session:
    tarif = session.get(Tarif, 1)


class Abrechnung:
    """ Klasse Abrechnung. Hier befinden sich die Methoden zur Berechnung der Verbrauchsdaten"""

    def __init__(self, eingegebener_zaehlerstand):
        self.eingegebener_zaehlerstand = eingegebener_zaehlerstand

    @classmethod
    def from_database(cls, eingegebener_zaehlerstand):
        return cls(eingegebener_zaehlerstand)

    @property
    def verbrauch(self):
        return self.eingegebener_zaehlerstand - tarif.zaehlerstand_letzte_abrechnung

    @property
    def arbeitspreis_netto(self):
        return self.verbrauch * tarif.arbeitspreis / 100

    @property
    def arbeitspreis_brutto(self):
        return self.arbeitspreis_netto * tarif.mehrwertsteuer

    # Abrechnungen
    # Berechnung Grundpreis
    @property
    def grundpreis_tagesgenau_brutto(self):
        return self.grundpreis_tagesgenau_netto * tarif.mehrwertsteuer

    # Berechnung Gesamtbetrag
    @property
    def gesamtbetrag_netto(self):
        return self.arbeitspreis_netto + self.grundpreis_tagesgenau_netto

    @property
    def gesamtbetrag_brutto(self):
        return self.arbeitspreis_brutto + self.grundpreis_tagesgenau_brutto

    # Ermittele Grundpreis
    @property
    def grundpreis_tagesgenau_netto(self):
        tage = datetime.now() - datetime(2023, 9, 30)
        tage = tage.total_seconds()
        tage = tage / 86400
        betrag_tag = tarif.grundpreis / 365
        return betrag_tag * tage

    # Ermittele Abschlag
    @property
    def bisheriger_gezahlter_abschlag(self):
        monate = datetime.now() - datetime(2023, 10, 15)
        monate = monate.total_seconds()
        monate = math.floor(monate / 2419200) + 1
        return tarif.monatlicher_abschlag * monate

    @property
    def abschlag_ende_des_jahres(self):
        return tarif.monatlicher_abschlag * 12

    # Grundpreis abz. Abschlag bis jetzt
    @property
    def aktuelle_kosten_abz_bisheriger_abschlag(self):
        return self.bisheriger_gezahlter_abschlag - self.gesamtbetrag_brutto

    # Grundpreis abz. Ende des Jahres
    @property
    def aktuelle_kosten_abz_bisheriger_abschlag_ende_des_jahres(self):
        return self.abschlag_ende_des_jahres - self.gesamtbetrag_brutto
Verbrauchsrechner.py:

Code: Alles auswählen

import sys
from PySide6 import QtWidgets
from GUI.Verbrauchsrechner_gui import Ui_Hauptdialog
from Abrechnung import Abrechnung


class Verbrauchsrechner(QtWidgets.QDialog):
    """Main Klasse hier startet das Programm"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Hauptdialog()
        self.ui.setupUi(self)
        # Slot eingerichtet
        self.ui.button_OK.clicked.connect(self.berechne)

    # Slot
    def berechne(self):
        eingegebener_zaehlerstand = self.ui.spin_box_eingabe.value()
        abrechnung = Abrechnung.from_database(eingegebener_zaehlerstand)
        self.ui.arbeitspreis_netto.setText(f"{abrechnung.arbeitspreis_netto:.2f} €")
        self.ui.arbeitspreis_brutto.setText(f"{abrechnung.arbeitspreis_brutto:.2f} €")
        self.ui.grundpreis_netto.setText(f"{abrechnung.grundpreis_tagesgenau_netto:.2f} €")
        self.ui.grundpreis_brutto.setText(f"{abrechnung.grundpreis_tagesgenau_brutto:.2f} €")
        self.ui.gesamtpreis_netto.setText(f"{abrechnung.gesamtbetrag_netto:.2f} €")
        self.ui.gesamtpreis_brutto.setText(f"{abrechnung.gesamtbetrag_brutto:.2f} €")
        self.ui.abschlag_bis_jetzt.setText(f"{abrechnung.bisheriger_gezahlter_abschlag:.2f} €")
        self.ui.abschlag_ende_des_jahres.setText(f"{abrechnung.abschlag_ende_des_jahres:.2f} €")
        self.ui.gp_abz_abschlag_bj.setText(f"{abrechnung.aktuelle_kosten_abz_bisheriger_abschlag:.2f} €")
        self.ui.gp_abz_abschlag_ej.setText(f"{abrechnung.aktuelle_kosten_abz_bisheriger_abschlag_ende_des_jahres:.2f}")


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    dialog = Verbrauchsrechner()
    dialog.show()
    sys.exit(app.exec())
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Weder `engine` noch `tarif` sollte auf Modulebene existieren. Man muss Module importieren können ohne das so weitreichende Sachen passieren wie Verbindungen zu Datenbanken und Abfragen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Hi @__blackjack__,

meine Lösung wäre die Session und das Tarif Objekt in den Konstrukter von der Abrechnung zu setzen.

Code: Alles auswählen

import math
from datetime import datetime
from sqlalchemy.orm import Session
from Datenbank.Datenbankverbindung import Tarif, Engine


class Abrechnung:
    """ Klasse Abrechnung. Hier befinden sich die Methoden zur Berechnung der Verbrauchsdaten"""

    def __init__(self, eingegebener_zaehlerstand):
        self.eingegebener_zaehlerstand = eingegebener_zaehlerstand
        # engine = Engine()
        with Session(engine) as session:
            self.tarif = session.get(Tarif, 1)

    @classmethod
    def from_database(cls, eingegebener_zaehlerstand):
        return cls(eingegebener_zaehlerstand)

    @property
    def verbrauch(self):
        return self.eingegebener_zaehlerstand - self.tarif.zaehlerstand_letzte_abrechnung

    @property
    def arbeitspreis_netto(self):
        return self.verbrauch * self.tarif.arbeitspreis / 100
Für die Engine. Wenn ich für sie eine eigene Klasse erstelle und diese, vielleicht, von "create_engine" erbt. Wäre dies eine Lösung?

Skizze:

Code: Alles auswählen

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Relationship, Mapped, mapped_column
from typing import List, Optional


class Engine(create_engine):
    def __init__(self):
        self.make_url('sqlite:///Datenbank/verbrauchsrechner.db')


class Base(DeclarativeBase):
    pass

Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Master_Shredder: Beides funktioniert offensichtlich so nicht. Im ersten Quelltext ist `engine` nicht definiert, und im zweiten wird versucht von einer Funktion zu erben.

Warum heisst `from_database()` so wie es heisst? Von welcher Datenbank? *Die* Methode braucht ja offenbar eine Datenbank die nicht einfach so vom Himmel fällt, sondern dort als Argument übergeben werden sollte. Also die Sitzung. In der Methode sollte auch die Abfrage von dem Tarif-Objekt passieren, denn sonst kann man kein `Abrechnung`-Objekt erstellen, ohne auch eine Verbindung zu einer Datenbank zu haben. Zum Beispiel für Tests oder zur Fehlersuche möchte man das auch mal mit einem Tarif-Objekt machen das man nicht erst aus einer Datenbank laden muss.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Ahh :shock: sorry ist mir gar nicht aufgefallen. Habe mich die ganze Zeit auf die Funktionen konzentriert und habe die Bezeichnung nicht beachtet. Heißt jetzt "eingabe_zaehlerstand".

Also wenn ich die engine auf Modul Ebene lasse geht die Abrechnung.
In der Methode sollte auch die Abfrage von dem Tarif-Objekt passieren
Wieso soll ich die Abfrage wieder in der Methode machen? Dann muss ich doch wider die Attribute in die __init__ schreiben und dann habe ich doch wieder die Duplizierung wie @snafu meinte?
sonst kann man kein `Abrechnung`-Objekt erstellen, ohne auch eine Verbindung zu einer Datenbank zu haben.
:?: Wie soll das den gehen? Ich muss die Werte doch irgend wo speichern.?
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Master_Shredder: Da findet keine Duplizierung statt. Eine `__init__()` sollte so einfach wie möglich sein, ohne irgendwelche komplizierten Aktionen wenn man da *einfach* Objekte zum testen erstellen können möchte. Und das geht in dem man einfach ein Tarif-Objekt erstellt. Ich verstehe die Frage da nicht so wirklich denn das muss man ja auch machen wenn man die Werte in der Datenbank speichern möchte. Die müssen da ja auch irgendwie rein kommen. Das ginge ja nicht wenn man sie nur abfragen könnte. So ein Objekt kann man auch erstellen in dem man `Tarif` mit entsprechenden Argumenten aufruft.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Master_Shredder hat geschrieben: Dienstag 13. Februar 2024, 17:36
In der Methode sollte auch die Abfrage von dem Tarif-Objekt passieren
Wieso soll ich die Abfrage wieder in der Methode machen? Dann muss ich doch wider die Attribute in die __init__ schreiben und dann habe ich doch wieder die Duplizierung wie @snafu meinte?
Ja, und ich schrieb auch, wie man das löst: Indem man nur ein Tarif()-Objekt übergibt anstelle der einzelnen Tarif()-Attribute. Es ist nicht ungewöhnlich, dass eine Klasse ein bestimmtes Interface einer anderen Klasse erwartet. Der Tarif wird damit sozusagen zum Werkzeug der Abrechnung. Solange die Abhängigkeit nur ein eine Richtung besteht, ist das okay. Es muss nicht jede Instanz völlig isoliert ihr Ding machen. Denn sonst hat man im Endeffekt ja bloß als Klasse verkleidete Funktionen. Das ist auch an Karneval ein Code Smell. ;)

Somit also:

Code: Alles auswählen

def __init__(self, tarif, ...)
Damit ist man auch unabhängig von einer Datenbank-Verbindung und Tarif könnte seine Daten aus einer andere Quelle wie einer JSON-Datei oder Nutzereingaben bezogen haben. Das heißt, die Zuständigkeit zur Bereitstellung der Daten verbleibt komplett im Tarif und es obliegt dem Aufrufer der Abrechnung, welche Tarif-Implementierung er wählt.
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Indem man nur ein Tarif()-Objekt übergibt anstelle der einzelnen Tarif()-Attribute. Es ist nicht ungewöhnlich, dass eine Klasse ein bestimmtes Interface einer anderen Klasse erwartet.
Achso. Ja das ist ja cool.
Habe es so umgesetzt. Hoffe es kommt so hin?

Code: Alles auswählen

from Datenbank.Datenbankverbindung import Tarif


class Abrechnung:
    """ Klasse Abrechnung. Hier befinden sich die Methoden zur Berechnung der Verbrauchsdaten"""

    def __init__(self, eingegebener_zaehlerstand, tarif):
        self.eingegebener_zaehlerstand = eingegebener_zaehlerstand
        self.tarif = tarif

    @classmethod
    def eingabe_zaehlerstand(cls, eingegebener_zaehlerstand, session):
        session = session
        tarif = session.get(Tarif, 1)

        return cls(eingegebener_zaehlerstand, tarif)

    @property
    def verbrauch(self):
        return self.eingegebener_zaehlerstand - self.tarif.zaehlerstand_letzte_abrechnung
@__blackjack__
das muss man ja auch machen wenn man die Werte in der Datenbank speichern möchte. Die müssen da ja auch irgendwie rein kommen.
Ja, ehrlich gesagt habe ich die mit "DB Browser für SQLite" reingeschrieben :D .

Mit dem einfügen im Programm habe ich noch so Probleme. Das will nicht gehen.

Code: Alles auswählen

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Relationship, Mapped, mapped_column, Session
from typing import List, Optional

engine = create_engine('sqlite:///Datenbank/verbrauchsrechner.db')


class Base(DeclarativeBase):
    pass


class Vertragsdaten(Base):
    __tablename__ = 'vertragsdaten'

    vertragsdaten_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    versorger: Mapped[Optional[str]]
    vertragsbeginn: Mapped[Optional[str]]
    tarif: Mapped[List["Tarif"]] = Relationship(back_populates="vertragsdaten")


with Session(engine) as vertragsdaten_session:
    eingabe_vertragsdaten = Vertragsdaten(versorger="Energie GmbH",
                                          vertragsbeginn="01.01.2024")

    vertragsdaten_session.add_all([eingabe_vertragsdaten])
    vertragsdaten_session.commit()


class Tarif(Base):
    __tablename__ = 'tarif'

    tarif_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    arbeitspreis: Mapped[Optional[float]]
    grundpreis: Mapped[Optional[float]]
    mehrwertsteuer: Mapped[Optional[float]]
    zaehlerstand_letzte_abrechnung: Mapped[Optional[float]]
    monatlicher_abschlag: Mapped[Optional[float]]
    vertragsdaten_id: Mapped[int] = mapped_column(ForeignKey("vertragsdaten.vertragsdaten_id"))
    vertragsdaten: Mapped["Vertragsdaten"] = Relationship(back_populates="tarif")


with Session(engine) as tarif_session:
    eingabe_tarif = Tarif(arbeitspreis=30.7,
                          grundpreis=150.5,
                          mehrwertsteuer=1.19,
                          monatlicher_abschlag=35,
                          zaehlerstand_letzte_abrechnung=32000)

    tarif_session.add_all([eingabe_tarif])
    tarif_session.commit()
Bekomme immer Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/clsregistry.py", line 515, in _resolve_name
    rval = d[token]
           ~^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/_collections.py", line 346, in __missing__
    self[key] = val = self.creator(key)
                      ^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/clsregistry.py", line 483, in _access_cls
    return self.fallback[key]
           ~~~~~~~~~~~~~^^^^^
KeyError: 'Tarif'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/masterblack/PycharmProjects/Verbrauchsrechner/Verbrauchsrechner.py", line 5, in <module>
    from Datenbank.Datenbankverbindung import engine
  File "/home/masterblack/PycharmProjects/Verbrauchsrechner/Datenbank/Datenbankverbindung.py", line 22, in <module>
    eingabe_vertragsdaten = Vertragsdaten(versorger="Energie GmbH",
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 4, in __init__
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state.py", line 561, in _initialize_instance
    manager.dispatch.init(self, args, kwargs)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 499, in __call__
    fn(*args, **kw)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4391, in _event_on_init
    instrumenting_mapper._check_configure()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 2386, in _check_configure
    _configure_registries({self.registry}, cascade=True)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4199, in _configure_registries
    _do_configure_registries(registries, cascade)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4240, in _do_configure_registries
    mapper._post_configure_properties()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 2403, in _post_configure_properties
    prop.init()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/interfaces.py", line 579, in init
    self.do_init()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/relationships.py", line 1638, in do_init
    self._setup_entity()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/relationships.py", line 1852, in _setup_entity
    self._clsregistry_resolve_name(argument)(),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/clsregistry.py", line 519, in _resolve_name
    self._raise_for_name(name, err)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/clsregistry.py", line 500, in _raise_for_name
    raise exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: When initializing mapper Mapper[Vertragsdaten(vertragsdaten)], expression 'Tarif' failed to locate a name ('Tarif'). If this is a class name, consider adding this relationship() to the <class 'Datenbank.Datenbankverbindung.Vertragsdaten'> class after both dependent classes have been defined.

Process finished with exit code 1
Wenn ich dann den Schlüssel auskommentiere und über Verbrauchsrechner(Main) starte kommt das:

Code: Alles auswählen

/usr/local/bin/python3.12 /home/masterblack/PycharmProjects/Verbrauchsrechner/Verbrauchsrechner.py 
Traceback (most recent call last):
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1969, in _exec_single_context
    self.dialect.do_execute(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 922, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: vertragsdaten

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/masterblack/PycharmProjects/Verbrauchsrechner/Verbrauchsrechner.py", line 5, in <module>
    from Datenbank.Datenbankverbindung import engine
  File "/home/masterblack/PycharmProjects/Verbrauchsrechner/Datenbank/Datenbankverbindung.py", line 26, in <module>
    vertragsdaten_session.commit()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1969, in commit
    trans.commit(_to_root=True)
  File "<string>", line 2, in commit
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1256, in commit
    self._prepare_impl()
  File "<string>", line 2, in _prepare_impl
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1231, in _prepare_impl
    self.session.flush()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4312, in flush
    self._flush(objects)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4447, in _flush
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4408, in _flush
    flush_context.execute()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 466, in execute
    rec.execute(self)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 642, in execute
    util.preloaded.orm_persistence.save_obj(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 93, in save_obj
    _emit_insert_statements(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 1227, in _emit_insert_statements
    result = connection.execute(
             ^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1416, in execute
    return meth(
           ^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/sql/elements.py", line 517, in _execute_on_connection
    return connection._execute_clauseelement(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1639, in _execute_clauseelement
    ret = self._execute_context(
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1848, in _execute_context
    return self._exec_single_context(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1988, in _exec_single_context
    self._handle_dbapi_exception(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 2344, in _handle_dbapi_exception
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1969, in _exec_single_context
    self.dialect.do_execute(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 922, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: vertragsdaten
[SQL: INSERT INTO vertragsdaten (versorger, vertragsbeginn) VALUES (?, ?)]
[parameters: ('Energie GmbH', '01.01.2024')]
(Background on this error at: https://sqlalche.me/e/20/e3q8)

Process finished with exit code 1
Und über Datenbankverbindung direkt:

Code: Alles auswählen

/usr/local/bin/python3.12 /home/masterblack/PycharmProjects/Verbrauchsrechner/Datenbank/Datenbankverbindung.py 
Traceback (most recent call last):
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3293, in raw_connection
    return self.pool.connect()
           ^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 452, in connect
    return _ConnectionFairy._checkout(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 1269, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 716, in checkout
    rec = pool._do_get()
          ^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 169, in _do_get
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 167, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 393, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 678, in __init__
    self.__connect()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 902, in __connect
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 898, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/create.py", line 645, in connect
    return dialect.connect(*cargs, **cparams)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 616, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: unable to open database file

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/masterblack/PycharmProjects/Verbrauchsrechner/Datenbank/Datenbankverbindung.py", line 26, in <module>
    vertragsdaten_session.commit()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1969, in commit
    trans.commit(_to_root=True)
  File "<string>", line 2, in commit
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1256, in commit
    self._prepare_impl()
  File "<string>", line 2, in _prepare_impl
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1231, in _prepare_impl
    self.session.flush()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4312, in flush
    self._flush(objects)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4447, in _flush
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4408, in _flush
    flush_context.execute()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 466, in execute
    rec.execute(self)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 642, in execute
    util.preloaded.orm_persistence.save_obj(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 60, in save_obj
    for (
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 221, in _organize_states_for_save
    for state, dict_, mapper, connection in _connections_for_states(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 1736, in _connections_for_states
    connection = uowtransaction.transaction.connection(base_mapper)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 2, in connection
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 995, in connection
    return self._connection_for_bind(bind, execution_options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 2, in _connection_for_bind
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1129, in _connection_for_bind
    conn = self._parent._connection_for_bind(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 2, in _connection_for_bind
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1143, in _connection_for_bind
    conn = bind.connect()
           ^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3269, in connect
    return self._connection_cls(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 147, in __init__
    Connection._handle_dbapi_exception_noconnection(
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 2431, in _handle_dbapi_exception_noconnection
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 3293, in raw_connection
    return self.pool.connect()
           ^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 452, in connect
    return _ConnectionFairy._checkout(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 1269, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 716, in checkout
    rec = pool._do_get()
          ^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 169, in _do_get
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/impl.py", line 167, in _do_get
    return self._create_connection()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 393, in _create_connection
    return _ConnectionRecord(self)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 678, in __init__
    self.__connect()
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 902, in __connect
    with util.safe_reraise():
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/pool/base.py", line 898, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/create.py", line 645, in connect
    return dialect.connect(*cargs, **cparams)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/masterblack/.local/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 616, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
(Background on this error at: https://sqlalche.me/e/20/e3q8)

Process finished with exit code 1
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Master_Shredder: Da ist schon wieder/immer noch Code auf Modulebene der Sachen macht die über das Definieren von Konstanten, Funktionen, und Klassen hinaus geht. Und der Versucht etwas zu verwenden (`Tarif`) was zu dem Zeitpunkt noch gar nicht existiert. Einer der Gründe warum man so etwas auf Modulebene nicht macht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Da ist schon wieder/immer noch Code auf Modulebene
:?: Wo denn?? Die engine ja, da weiß ich noch nicht wie ich es machen soll. Oder der import bei Abrechnung? Den bekomme ich aber auch von der IDE angegeben.

Code: Alles auswählen

from Datenbank.Datenbankverbindung import *
Besser???
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Master_Shredder: `engine` wird dort definiert und dann gibt es zwei ``with`` die damit was machen, und das nur weil das Modul importiert wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Also soll ich ein Session Objekt ohne with Anweisung erstellen?
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Master_Shredder: Warum das denn jetzt? Natürlich mit ``with`` aber nicht auf Modulebene so dass das einfach durch importieren des Moduls bereits ausgeführt wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Üblicherweise macht man das mit einer Funktion "main" und dem Nachsatz:

Code: Alles auswählen

if __name__ == "__main__": 
     main()
Kommt dir das bekannt vor?
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

aber nicht auf Modulebene
Sorry, ich weiß gerade nicht mehr weiter. Hilf mir mal bitte.

Bin jetzt raus :? :

Code: Alles auswählen

def main():
    engine = create_engine('sqlite:///Datenbank/verbrauchsrechner.db')
    with Session(engine) as session:
       

Code: Alles auswählen

class Vertragsdaten(Base):
    __tablename__ = 'vertragsdaten'

    vertragsdaten_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    versorger: Mapped[Optional[str]]
    vertragsbeginn: Mapped[Optional[str]]
    tarif: Mapped[List["Tarif"]] = Relationship(back_populates="vertragsdaten")


vertragsdaten_session = Verbrauchsrechner.main()
eingabe_vertragsdaten = Vertragsdaten(versorger="Energie GmbH",
                                      vertragsbeginn="01.01.2024")

vertragsdaten_session.add_all([eingabe_vertragsdaten])
vertragsdaten_session.commit()
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und da ist jetzt am ``vertragsdaten_session = …`` wieder Code auf Modulebene der da nicht hingehört.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Master_Shredder hat geschrieben: Donnerstag 15. Februar 2024, 15:01
aber nicht auf Modulebene
Sorry, ich weiß gerade nicht mehr weiter. Hilf mir mal bitte.
Der Code gehoert einfach in eine Funktion. Das ist alles. main ist natuerlich quatsch, das waere nur, wenn man das Modul alleine ausfuehren will. Stattdessen mus das einfach nur

Code: Alles auswählen

def setup_session():
	engine = create_engine('sqlite:///Datenbank/verbrauchsrechner.db')
        return Session(engine)


sein. Und dann benutzt man das natuerlich woanders wie gewohnt:

Code: Alles auswählen


def lege_eintrag_an():
    session = setup_session()
    with session:
        eingabe_vertragsdaten = Vertragsdaten(versorger="Energie GmbH",
                                      vertragsbeginn="01.01.2024")
        vertragsdaten_session.add_all([eingabe_vertragsdaten])
        vertragsdaten_session.commit()
Also nochmal im Chor: KEINE AUSGEFUEHRTEN ANWEISUNGEN AUF MODULEBENE. Nur importe, Klassen, und Funktionen.
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

Ahh danke @__deets__,
jetzt weis ich auch was gemeint war! Durch die Einrückung bin ich wieder auf die "Modulebene" geraten. Ich hatte gedanklich in der Klasse ein Endtag :roll: .

Nun sieht es so aus:

Code: Alles auswählen

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Relationship, Mapped, mapped_column, Session
from typing import List, Optional


def setup_session():
    engine = create_engine('sqlite:///Datenbank/verbrauchsrechner.db')
    return Session(engine)


class Base(DeclarativeBase):
    pass


class Vertragsdaten(Base):
    __tablename__ = 'vertragsdaten'

    vertragsdaten_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    versorger: Mapped[Optional[str]]
    vertragsbeginn: Mapped[Optional[str]]
    tarif: Mapped[List["Tarif"]] = Relationship(back_populates="vertragsdaten")


class Tarif(Base):
    __tablename__ = 'tarif'

    tarif_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    arbeitspreis: Mapped[Optional[float]]
    grundpreis: Mapped[Optional[float]]
    mehrwertsteuer: Mapped[Optional[float]]
    zaehlerstand_letzte_abrechnung: Mapped[Optional[float]]
    monatlicher_abschlag: Mapped[Optional[float]]
    vertragsdaten_id: Mapped[int] = mapped_column(ForeignKey("vertragsdaten.vertragsdaten_id"))
    vertragsdaten: Mapped["Vertragsdaten"] = Relationship(back_populates="tarif")


def eintrag_einfuegen():
    session = setup_session()
    with session:
        eingabe_vertragsdaten = Vertragsdaten(versorger="Energie GmbH",
                                              vertragsbeginn="01.01.2024")

        eingabe_tarif = Tarif(arbeitspreis=30.7,
                              grundpreis=150.5,
                              mehrwertsteuer=1.19,
                              monatlicher_abschlag=35,
                              zaehlerstand_letzte_abrechnung=32000)

        session.add_all([eingabe_vertragsdaten, eingabe_tarif])
        session.commit()

Code: Alles auswählen

from Datenbank.Datenbankverbindung import *


class Abrechnung:
    """ Klasse Abrechnung. Hier befinden sich die Methoden zur Berechnung der Verbrauchsdaten"""

    def __init__(self, eingegebener_zaehlerstand, tarif):
        self.eingegebener_zaehlerstand = eingegebener_zaehlerstand
        self.tarif = tarif

    @classmethod
    def eingabe_zaehlerstand(cls, session, eingegebener_zaehlerstand):
        session = session
        tarif = session.get(Tarif, 1)

        return cls(eingegebener_zaehlerstand, tarif)

    @property
    def verbrauch(self):
        return self.eingegebener_zaehlerstand - self.tarif.zaehlerstand_letzte_abrechnung
Habe extra in der main() aufgerufen da wir ja, so wie ich es verstanden habe, beabsichtigen auch ohne Datenbankverbindung die Tabellen Attribute zu erhalten.

Code: Alles auswählen

  def berechne(self):
        session = setup_session()
        eingegebener_zaehlerstand = self.ui.spin_box_eingabe.value()
        abrechnung = Abrechnung.eingabe_zaehlerstand(eingegebener_zaehlerstand, session)
        self.ui.arbeitspreis_netto.setText(f"{abrechnung.arbeitspreis_netto:.2f} €")
 ..............        
        
def main():
    eintrag_einfuegen()

    app = QtWidgets.QApplication(sys.argv)
    dialog = Verbrauchsrechner()
    dialog.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()
Master_Shredder
User
Beiträge: 18
Registriert: Freitag 2. Februar 2024, 18:25

@__blackjack__ kannst du oder @whoever mir sagen, wie ich es machen soll? Ich komme selbst nicht mehr weiter und habe auch keine Zeit mehr.

Grüße Master_Shredder
Antworten