SQLAlchemy: Objecte mit Listen speichern

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
homerunjack
User
Beiträge: 24
Registriert: Donnerstag 21. Juli 2016, 12:12

Donnerstag 4. Mai 2017, 13:17

Hallo,

habe vor wenigen Tagen angefangen, mich mit SQLAlchemy zu beschäftigen. Eine Sache habe ich jedoch nicht ganz verstanden.
Es geht um die Geschichte ForeignKey. Wie kann ich ein Object anlegen/speichern, welches auch z.B. Listen beinhaltet.

Code: Alles auswählen

class Person(Base):
	__tablename__ = 'Personen'
	personenID = Column(Integer, primary_key=True)
	name = Column(String)
	termine = relationship('Termine')

class Termin(Base):
	__tablename__ = 'Termine'
	terminID = Column(Integer, primary_key=True)
	datum = Column(String)
	personenID = Colum(Integer, ForeignKey('Personen.personenID'))
	person = relationship('Person')
Was muss ich tun, um ein Objekt zu speichern, dass aus einem Namen und eine Liste aus Terminen besteht?

Code: Alles auswählen

class neuePerson():
	
	def __init__(self, mName):
		self.name = mName
		self.termine = list()
		
	def setTermin(self, mTermin):
		self.termine.append(mTermin)
Muss ich diese Daten gesondert in den einzelnen Tabellen speichern oder kann man diese auch durch ein Objekt speichern? (Bzw. was ist das Stichwort, wenn ich danach suchen will?)

Beste Grüße
homerunjack
Zuletzt geändert von Anonymous am Donnerstag 4. Mai 2017, 14:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
noisefloor
User
Beiträge: 2476
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Donnerstag 4. Mai 2017, 14:12

Hallo,

eigentlich will man das so nicht, also eine Liste speichern.

Der Ansatz ist, wie du es im Prinzip ja schon machst, eine Tabelle `Person`zu haben und eine Tabelle `Termin`, die eine "One-to-Many" Beziehung haben, d.h. jede Person kann beliebig viele Termine haben, aber jeder Termin kann nur genau einer Person zugeordnet sein.

Die Liste der Termin für eine Person liefert dir dann die entsprechende Datenbankabfrage.

Abgesehen davon macht IMHO eine Klasse "neue Person" wenig Sinn, weil eine Klasse _nur_ zum Anlegen einer Person in der Regel wenig sinnvoll ist. Vielmehr würde man das eher über einen Funktionsaufruf `create_new_person` machen, die eine neue Person in der DB anlegt. Dann bekommst du eine Objekt für eine (jetzt existierende) Person, für die man dann über entsprechende Methoden Termin anlegen und abfragen kann.

Gruß, noisefloor
BlackJack

Donnerstag 4. Mai 2017, 14:39

@homerunjack: Die Tabellennamen würde ich als Einzahl schreiben, denn so ein Tabellenschema beschreibt, genau wie eine Klasse, *eine* Person, oder *einen* Termin.

Ferner würde ich bei SQL-Bezeichnern alles klein schreiben. Manche DBMS berücksichtigen Gross-/Kleinschreibung, manche nicht, bei manchen hängt es von Einstellungen ab. Am sichersten fährt man also wenn man alles klein schreibt. klein_mit_unterstrichen würde dann auch den Namenskonventionen in Python entsprechen, an die Du Dich auch nicht hältst.

IDs als Primärschlüssel nenne ich immer nur `id`. Da *nochmal* den Klassen-/Schamanamen zu wiederholen bringt keinen Mehrwert. `person.person_id` hat keinen Mehrwert gegenüber `person.id`.

Die `relationship` würde man nur auf einer Seite definieren. Also zum Beispiel auf `Termin` als `person = relationship(Person, backref='termine').

Warum ist das `datum` eine Zeichenkette? Dafür gibt es eigene Datentypen.

Was soll das `m` bei den Argumenten bedeuten? Kryptische, sinnlose Präfixe sollte man nicht verwenden.

Zur Frage: Du erstellst ein Objekt von `Person` und die `Termin`-Objekte und hängst dann alle `Termin`-Objekte mit `append()` an das `termine`-Attribut von `Person` und fügst dann `Person` zur Sitzung hinzu (kann man auch am Anfang machen) und commitest das dann.
homerunjack
User
Beiträge: 24
Registriert: Donnerstag 21. Juli 2016, 12:12

Freitag 5. Mai 2017, 07:58

Hallo,

vielen Dank für die wertvollen Tipps. Das bringt mich wirklich weiter! :D

Beste Grüße
homerunjack
Antworten