Lesen und Schreiben von Klassen in CSV
Noch eine Frage, in diesem Zusammenhang, wo ebenfalls alles Recherchieren und Probieren nichts geholfen hat: Ich möchte die Objekte nicht nur schreiben, sondern auch lesen, und sie kommen dann in eine Datenbank, und verwenden hierfür SQLAlchemy. Habt ihr einen weiteren Tipp für mich?
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Hm, bei SQLAlchemy hat man dann doch schon die ORM-Klassen, beziehungsweise kann man sich ja Mapper auf vorhandene Klassen erstellen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Hm, ich sehe schon: Ich muss mich noch tiefgehender mit Python beschäftigen, Kenntnisse anderer Programmiersprachen erweitert um Comprehensions reicht nicht aus. Die Python-Welt ist doch größer als vermutet. Vor allem das Konzept der Metaklassen ist mir ziemlich neu. Gibt es da eine Einführung, die nicht bei 0 anfängt? Also die nicht unbedingt damit anfängt, wie man den Rechner einschaltet und Python installiert? Und auch keine, die bei 150 anfängt ("Was unterscheidet dieses obskure Modul von jenem?").
Ich habe einstweilen mal probiert, attrib und SQLAlchemy zu verheiraten. Leider kein Erfolg bis jetzt.
Geht, aber halt ohne attr:
Der naive Ansatz mit attr geht nicht, weil angeblich kein Primärschlüssel definiert ist:
Ich habe einstweilen mal probiert, attrib und SQLAlchemy zu verheiraten. Leider kein Erfolg bis jetzt.
Geht, aber halt ohne attr:
Code: Alles auswählen
class Test(Base):
__tablename__ = "test"
a = Column(Integer, primary_key=True)
b = Column(Integer)
Code: Alles auswählen
@attrs(frozen=True)
class Test(Base):
__tablename__ = "test"
a = attrib(Column(Integer, primary_key=True))
b = attrib(Column(Integer))
Das man mit SQLAlchemy CSV lesen/schreiben kann, halte ich für unwahrscheinlich. Und eine Kombination mit attrs ist nicht sinnvoll, SA selbst ist ja hoch declarative, und baut sich eigene Klasse - das kommt sich alles in die Quere. - ok, snafu hat gezeigt, dass es geht. Ich finde es immer noch etwas komisch, aber gut.
Statt Metaklassen sind vielleicht auch eher Klassendekoratoren (wie attrs selbst sie benutzt) eine gute Wahl. Damit kannst du zb die erzeugte Methode zum iterieren der Attribute so ummanteln, dass sie vorher noch den Klassennamen ausgibt. Und gleichzeitig eine globale Registry für die genannte Factory füttert, du musst ja eine Zuordnung von Klassenname auf Klasse hinbekommen, und die restlichen Werte dann Typwandeln und einlesen basierend auf der Attribut-Deklaration.
Das ist aber auch alles ganz schön viel Maschinerie. Über wieviele Klasse reden wir denn hier? Denn man kann das bei einigen wenigen ja auch einfach erstmal “zu Fuß” programmieren. Die ganze Meta-Magie ist fein, aber auch oft etwas undurchdringbar.
Statt Metaklassen sind vielleicht auch eher Klassendekoratoren (wie attrs selbst sie benutzt) eine gute Wahl. Damit kannst du zb die erzeugte Methode zum iterieren der Attribute so ummanteln, dass sie vorher noch den Klassennamen ausgibt. Und gleichzeitig eine globale Registry für die genannte Factory füttert, du musst ja eine Zuordnung von Klassenname auf Klasse hinbekommen, und die restlichen Werte dann Typwandeln und einlesen basierend auf der Attribut-Deklaration.
Das ist aber auch alles ganz schön viel Maschinerie. Über wieviele Klasse reden wir denn hier? Denn man kann das bei einigen wenigen ja auch einfach erstmal “zu Fuß” programmieren. Die ganze Meta-Magie ist fein, aber auch oft etwas undurchdringbar.
Ich finde sogar, dass sich dataclasses besser in die Sprache einfügt als dieses attrs-Modul. Da brauche ich nur den @dataclass-Dekorator an die Klasse kleben und habe direkt die benötigte Magie.__deets__ hat geschrieben: ↑Freitag 19. November 2021, 13:46 Wenn man will, kann man ja aber auch https://docs.python.org/3/library/dataclasses.html benutzen. Das ist vielleicht nicht ganz so umfangreich, aber vieles kann es eben auch schon.
Und mit SQLAlchemy geht es wohl so: https://docs.sqlalchemy.org/en/14/orm/m ... tive-table
Für attrs geht das wohl so: https://docs.sqlalchemy.org/en/14/orm/m ... tive-table - aber das backend ist doch immer noch nicht CSV, was bringt das einem?
Und hier hat jemand ein Modul gebastelt, das dataclasses mit CSV-Daten befüllen kann: https://pypi.org/project/dataclass-csv/
Eben. Ich dachte, das wäre eventuell ganz einfach, sowas wie "importier einfach dieses Modul hier". Es scheint sich aber, wenn es mal funktionieren sollte, um einen ziemlichen Aufriss zu handeln. Es handelt sich auch bei mir um eine einzige Klasse, deshalb ist es das einfachste, wenn ich das mit weniger Library-Unterstützung mache, sonst schieße ich mit Kanonen auf Spatzen und fahre 10x soviel Boilerplate Code ein, um etwas zu sparen. Sparen um jeden Preis!__deets__ hat geschrieben: ↑Sonntag 21. November 2021, 12:32 Das ist aber auch alles ganz schön viel Maschinerie. Über wieviele Klasse reden wir denn hier? Denn man kann das bei einigen wenigen ja auch einfach erstmal “zu Fuß” programmieren. Die ganze Meta-Magie ist fein, aber auch oft etwas undurchdringbar.
Aber als Sekundäreffekt gab es viele wertvolle Einsichten in Python. Danke!
@zegru
Also eine Bibliothek empfiehlt sich dafür schon, damit man eben nicht alles zu Fuß machen muss. Dein Problem ist eher, dass du noch keinen einfachen Ansatz für dein Vorhaben gefunden hast. Wie gesagt, schau dir mal das dataclass-csv Modul näher an.
Hier etwas Beispiel-Code aus der Doku:
Also eigentlich relativ simpel und die Typ-Umwandlungen gibt's gratis dazu. Oder entspricht das nicht dem, was du dir vorgestellt hast?
Also eine Bibliothek empfiehlt sich dafür schon, damit man eben nicht alles zu Fuß machen muss. Dein Problem ist eher, dass du noch keinen einfachen Ansatz für dein Vorhaben gefunden hast. Wie gesagt, schau dir mal das dataclass-csv Modul näher an.
Hier etwas Beispiel-Code aus der Doku:
Code: Alles auswählen
@dataclass
class User:
firstname: str
email: str
age: int
with open(filename) as users_csv:
reader = DataclassReader(users_csv, User)
for row in reader:
print(row)
Leider kann ich ja dataclass nicht verwenden, da ich ja auch SQLAlchemy für meine Klasse hernehme. Ich verwende jetzt halt das Modul csv und habe eine zusätzliche Methode in der Klasse Test geschrieben, die mir die einzelnen Felder als Tupel zurück liefert. Ich iteriere dann über eine Liste von Test Objekten und rufe dort mit csv.writerow() das Ergebnis des Tupellieferanten des Objekts zurück. Lediglich Felder->Tupel mache ich also manuell.
Ahhhh. Das ist mir entgangen, dass es auch um SA Objekte geht. Aber dafür hat Snafu doch eine Integration von, \ SA & dataclasses gezeigt. Ob das dann in der Summe immer noch mit dataclasses_csv arbeitet, musst du ausprobieren.
Okay, wenn die dataclass wirklich nur Mittel zum Zweck ist und eigentlich nicht benötigt wird, dann würde ich den Gedanken wieder verwerfen. Ein Modul für die Umwandlung von SQLAlchemy-Klassen in CSV kenne ich nicht und habe auf die Schnelle auch nichts dazu gefunden. Da bleibt dir wohl nur der händische Weg, den du ja offenbar auch schon gehst.