@jerch: Ich habe mal eben auf der Schnelle einen halbwegs brauchbaren Quelltext zusammengesetzt. Leider kriege ich den Quelltext nicht auf drei Zeilen runter gebrochen.
Aber gehen wir mal Stück für Stück vor. Zunächst hier mein Modell. Du siehst, dass
Person() mehrere 1:n-Beziehungen pflegt. Hier habe ich nur mal 2x 1:n-Beziehungen genommen.
Code: Alles auswählen
import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship, backref
sqlite_uri = 'sqlite:///test.sqlite'
engine = sqlalchemy.create_engine(sqlite_uri, echo=True)
Base = declarative_base()
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)
first_middle_name = Column(String(255))
last_name = Column(String(100))
gender_id = Column(Integer, ForeignKey('person_gender.id'))
gender = relationship("PERSON_GENDER")
hair_color_id = Column(Integer, ForeignKey('person_hair_color.id'))
hair_color = relationship("PERSON_HAIR_COLOR")
class PERSON_GENDER(Base):
__tablename__ = "person_gender"
id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
gender = Column(String(50), nullable=False, unique=True)
class PERSON_HAIR_COLOR(Base):
__tablename__ = "person_hair_color"
id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
hair_color = Column(String(50), nullable=False, unique=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
Jetzt starte ich diese beiden Abfragen. Die
gender-Abfrage demonstriert, dass diese nicht klappen solle. Denn niemand ist vom Geschlecht her 'nix'. Für 'nix' können wir eben auch eine Situation vorstellen, dass der Benutzer beim Anlegen kein Geschlecht ausgesucht hat. Das heißt,
result_gender wird None sein.
Code: Alles auswählen
result_gender = session.query(PERSON_GENDER).filter(PERSON_GENDER.salutation=='nix').first()
result_hair_color = session.query(PERSON_HAIR_COLOR).filter(PERSON_HAIR_COLOR.salutation=='blond').first()
Jetzt tun wir mal so, als wollen wir den Datensatz anlegen: In dieser Variante werden ORM-Objekte an folgende Beziehung des
PERSON(): gender und hair_color. Das klappt aber nur solange, wie es ORM-Objekte wirklich gibt.
Code: Alles auswählen
person_one = PERSON(name_normally_used='Kevin',
alias_name = 'Pseudo_nick',
gender = result_gender,
hair_color = result_hair_color)
session.add(person_one)
session.commit()
Wir wissen aber, dass
PERSON() zwei Fremdschlüsselspalten hat: gender_id und hair_color_id. Und diese Saplten erlauben auch NULL - in Python wäre es None.
Code: Alles auswählen
result_gender = session.query(PERSON_GENDER).filter(PERSON_GENDER.salutation=='nix').first()
result_hair_color = session.query(PERSON_HAIR_COLOR).filter(PERSON_HAIR_COLOR.salutation=='blond').first()
# ternary conditional operator, wenn der Rückgabe Wert None ist, bekommt
# bekommen die Variablen None, ansonsten bekommen die ID
get_gender= None if result_person_gender is None else result_person_gender.id
get_hair_color = None if result_hair_color is None else result_hair_color .id
# Hier arbeiten wir nicht mit den ORM-Objekten,
# sondern mit IDs oder eben NOne und übergeben diese
# Werte direkt der Fremdschlüssel-Spalte und nicht der Beziehung
person_one = PERSON(name_normally_used='Kevin',
alias_name = 'Pseudo-Nick',
gender_id = get_gender,
hair_color_id = get_hair_color )
session.add(person_one)
session.commit()