Ich möchte diesen Beitrag wiederbeleben, weil ich denke, dass ich hier sehr gut anknüpfen kann. Ich stoße gerade, scheinbar, auf eine Grenze. Sirius3 hat ja bereits darauf hingewiesen, dass man mit ORM-Objekten arbeiten möchte, anstatt mit IDs. Soweit alles fein. Die Vorteile wurde von BlackJack schon erwähnt. Aber diese Arbeitsweise besagt ja auch, dass ein Objekt erfolgreich kreiiert sein muss, um dieses Objekt zum Beispiele an einer Beziehung zu übergeben. In meinem alten Beispiel war es die Verknüpfungstabelle mit einer n:m-Beziehung.
Nun folgende Situation: Ich arbeite gerade an einer 1:n-Beziehung. Auf der Benutzeroberfläche kann der Benutzer einige freie Texte in die
QLineEdit() eingeben. Zum Beispiel Namen, einer Person. Daneben gibt es auch ein paar
QComboBox(), die mit Daten einer anderen Tabelle gefüllt werden. Nehmen wir mal an, in einer
QComboBox() werden die Geschlechter geladen. Nun möchte der Benutzer eine Person anlegen, jedoch wählt die Person kein Geschlecht aus - ist auch keine Angabepflicht. Da nichts in der
QComboBox() ausgewählt wurde, schlägt die Abfrage fehl, und ein ORM-Objekt wird nicht erzeugt. Demzufolge übergebe ich einer Beziehung einen Wert, jedoch kein ORM-Objekt. Man könnte sich mit vielen Hilfsmitteln behelfen. Zum Beispiel kann man sagen, wenn die Abfrage des Geschlecht nicht erfolgreich war, da der Benutzer kein Geschlecht ausgewählt hat, dann soll das Geschlecht nicht an die Beziehung übergeben werden. Aber ich habe leider mehr als nur 2
QComboBox() auf der Oberfläche. Nach meiner Vorgehensweise müsste ich erst einmal nach und nach alles Abfragen überprüfen, ob diese oder jene Abfrage erfolgreich war und wenn etwas erfolgreich war, kann das erzeugte ORM-Objekt an die entsprechende Beziehung übergeben werden. Klingt sehr aufwendig und fehleranfällig.
Hier ein Pseudo-Beispiel:
Code: Alles auswählen
class PERSON(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
nickname = Column(String(255))
alias_name = Column(String (255))
name_normally_used = Column(String(50), nullable=False)
gender_id = Column(Integer, ForeignKey('person_gender.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
gender = relationship("PERSON_GENDER", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
hair_color_id = Column(Integer, ForeignKey('person_hair_color.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
hair_color = relationship("PERSON_HAIR_COLOR", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
eye_color_id = Column(Integer, ForeignKey('person_eye_color.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
eye_color = relationship("PERSON_EYE_COLOR", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
title_id = Column(Integer, ForeignKey('person_title.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
title = relationship("PERSON_TITLE", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
salutation_id = Column(Integer, ForeignKey('person_salutation.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
salutation = relationship("PERSON_SALUTATION", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
place_id = Column(Integer, ForeignKey('general_place.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
place = relationship("GENERAL_PLACE", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
religion_id = Column(Integer, ForeignKey('person_religion.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
religion = relationship("PERSON_RELIGION", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
relationship_status_id = Column(Integer, ForeignKey('person_relationship_status.id', onupdate="cascade", ondelete='SET NULL'), nullable=True, unique=True)
relationship_status = relationship("PERSON_RELATIONSHIP_STATUS", single_parent=True, cascade="all, delete-orphan")#passive_deletes=True)
result_gender = self._session.query(PERSON_GENDER).filter(PERSON_GENDER.gender=='komisch').first()
result_hair_color = self._session.query(PERSON_HAIR_COLOR).filter(PERSON_HAIR_COLOR.gender=='blond').first()
result_eye_color = self._session.query(PERSON_EYE_COLOR).filter(PERSON_EYE_COLOR.gender=='blau').first()
result_title = self._session.query(PERSON_TITLE).filter(PERSON_TITLE.gender=='Prof.').first()
result_salutation = self._session.query(PERSON_SALUTATION).filter(PERSON_SALUTATION.gender=='Herr').first()
result_place = self._session.query(GENERAL_PLACE).filter(GENERAL_PLACE.gender=='Mond').first()
result_religion = self._session.query(PERSON_RELIGION).filter(PERSON_RELIGION.gender=='Spagetti').first()
result_relationship_status = self._session.query(PERSON_RELATIONSHIP_STATUS).filter(PERSON_RELATIONSHIP_STATUS.gender=='ledig').first()
p1 = PERSON(name_normally_used ='Kevin', gender =result_gender, hair_color=result_hair_color,
eye_color =result_eye_color , title=result_title , salutation =result_salutation , place =result_place ,
religion =result_religion , relationship_status=result_relationship_status )
self._session.add(p1)
self._session.commit()
Zur Veranschaulichung soll diejenige Abfrage, die fehlschlägt, mittels der
first()-Funktion absichtlich ein None zurückgeben, denn wir gehen mal davon aus, dass das Geschlecht "
komisch", der Ort (place) "
Mond" und die Religion "
Spagetti"
nicht geben werden. Diese Abfragen sind somit nicht erfolgreich, und im nächsten Schritt wird trotzdem all die None-Werte an die entsprechenden Beziehungen übergeben.
Die Fehlermeldung könnte dann wie folgt aussehen:
AttributeError: 'None' object has no attribute '_sa_instance_state'
Ist ja auch logisch, denn es handelt sich hierbei keineswegs um ein ORM-Objekt. Und genau hier setze ich mit meinen Gedanken an. Wie gesagt, es gibt mehrere
QComboBox() auf meiner Oberfläche. Nun frage ich mich: soll ich durch die Brust ins Auge alle Abfragen auf ihren Erfolg hin überprüfen, und bei einer erfolgreichen Abfrage nur das entsprechende Objekt an die entsprechende Beziehung übergeben? Klingt sehr aufwendig. Ich habe nämlich gehofft, dass es sowas wie eine ignore-Einstellung gibt, wenn ein Objekt nicht existiert.