Seite 1 von 1

Typen erzwingen bei der Konstruktion von Objekten via Entrys

Verfasst: Freitag 17. Juni 2022, 16:25
von SinaS
Hallo zusammen,

ich benutze SQLAlchemy in Kombination mit einer SQLite-Datenbank. User sollen insb. über tkinter-Entrys selbst die Datenbank befüllen können, bspw. soll eine neue Kostenart angelegt werden können. Meine entsprechenden Klassen sehen ungefähr so aus:

Code: Alles auswählen

class Kostenart(Base):
    __tablename__ = "Kostenarten"
    rowid:int = Column(Integer, primary_key = True)
    name:str = Column(String(255))
Aus den Eingaben der User erstelle ich ein Objekt, das dann in die Datenbank gespeichert werden soll.

An anderer Stelle wurde ich dankenswerterweise darauf hingewiesen, dass die hier erwähnten Typen gar nicht erzwungen werden. Auch von Seiten der Datenbank passiert das nicht. Das ist dann problematisch, wenn ich nicht nur String-Felder habe, sondern auch andere Datentypen. Die User werden ja immer zunächst einen string in ein Entry eingeben.

Anders gefragt: Wie checke ich denn, ob die Dateneingaben der User zu meinen Type Hints passen und nehme entsprechende Konvertierungen vor, wenn es sein muss? Da gibt es bestimmt entsprechende Konzepte, aber mir fehlt der Einstieg in das Thema.

Danke euch und viele Grüße!

Re: Typen erzwingen bei der Konstruktion von Objekten via Entrys

Verfasst: Freitag 17. Juni 2022, 17:06
von __blackjack__
@SinaS: Da musst Du Dir Entries für die entsprechenden Datentypen schreiben, beziehungsweise die Daten von dort nicht einfach als Zeichenketten übernehmen, sondern eben umwandeln. Das Konzept heisst also: Schreib Code der macht was Du willst. 😉

Die Typannotationen finde ich problematisch. SQLAlchemy macht viel Magie und damit man die tatsächlich prüfen kann, muss das Prüfwerkzeug wissen was SQLAlchemy da macht. Also mindestens in Form eines Plugins.

Und wenn man das gar nicht oder nur schwer prüfen kann, dann braucht man die Annotationen auch für den menschlichen Leser nicht, denn in der Zeile steht ja der Typ den die Attribute später haben werden als erstes Argument von `Column()`. Sogar noch präziser in einigen Fällen denn das `str` beinhaltet ja auch Zeichenketten die Länger als 255 Zeichen sind, was ``String(255)`` präziser angibt.

Und auch das reicht ja noch nicht, denn man möchte ja beispielsweise auch in einigen Fällen Leereingaben als `None` und in der Datenbank dann `NULL` interpretieren. Es gibt Werte die müssen UNIQUE sein oder andere CONSTRAINTs erfüllen.

`rowid` sollte `id` heissen. Es gibt keinen Grund Implementierungsdetails von SQLite an der Stelle ins Programm zu holen.

Und Tabellennamen sind in der Regel wie Klassennamen und beschreiben *ein* Objekt, also Einzahl. Da SQL eigentlich nicht zwischen Gross- und Kleinschreibung von Bezeichnern unterscheidet, manche Datenbanken das (optional) aber doch tun, würde ich bei Kleinbuchstaben bleiben.