Seite 1 von 1

SqlAlchemy INSERT mit bereits vorhandenen ForeignKey

Verfasst: Donnerstag 27. März 2014, 08:44
von python_hulk
Hallo zusammen,

ich arbeite mich zur Zeit in sqlalchemy ein.
Leider bin ich gerade auf ein Thema gestoßen, bei dem ich nicht weiter weis.

In meiner Datenbank befinden sich zwei Objekte, nämlich Sendung und Adresse.
Jede Sendung hat eine Versender- und Empfängeradresse.
Alle id Spalten sind als Autoinkrement eingestellt.

Code: Alles auswählen

from sqlalchemy.orm import *
from sqlalchemy import *
from sqlalchemy.ext.declarative import *

engine = create_engine('sqlite:///testdb', echo=True)
Base = declarative_base()

class Adresse(Base):
        __tablename__ = 'Adresse'
        id = Column(Integer, primary_key=True)
        name1 = Column(String)


class Sendung(Base):
        __tablename__ = 'Sendung'
        id = Column(Integer, primary_key=True)
        empf_id = Column(String, ForeignKey('Adresse.id'))
        vers_id = Column(String, ForeignKey('Adresse.id'))

        empfaenger = relationship("Adresse", primaryjoin="Adresse.id==Sendung.empf_id")
        versender = relationship("Adresse", primaryjoin="Adresse.id==Sendung.vers_id")

vers1 = Adresse()
vers1.name1 = "Mustermann"
empf1 = Adresse()
empf1.name1 = "Musterfrau"

send1 = Sendung()
send1.versender = vers1
send1.empfaenger = empf1

Session = sessionmaker(bind=engine)
session = Session()

session.add(send1)
session.commit()
Soweit funktioniert es ja noch.
Jetzt zu meinen Problem:

Es kann vorkommen, dass eine neue Sendung eine Adresse hat, die bereits in der Datenbank vorhanden ist.

Code: Alles auswählen

vers2 = Adresse()
vers2.name1 = "Mustermann"
empf2 = Adresse()
empf2.name1 = "Musterfrau"

send2 = Sendung()
send2.versender = vers2
send2.empfaenger = empf2

session.add(send2)
session.commit()
Dies führt aber jetzt dazu, dass ich in meiner Adresse-Tabelle redundante Einträge habe.

Gibt es irgendeine Möglichkeit, die das verhindert.
Sprich, falls bereits eine Adresse mit gleichem Namen vorhanden ist, soll die neue Adresse verworfen werden
und der Sendung die bereits vorhandene in der Datenbank zugewiesen werden.

Ich hoffe ihr könnt mir weiterhelfen.

Gruß
python-hulk

Re: SqlAlchemy INSERT mit bereits vorhandenen ForeignKey

Verfasst: Donnerstag 27. März 2014, 09:07
von Balmung
Du schaust einfach vorher mit einem Query nach, ob eine Adresse mit dem entsprechenden Namen in der DB existiert.

So, oder so ähnlich:

Code: Alles auswählen

thename = 'Mustermann'
versender = session.query(Adresse).filter_by(name1=thename).first()  # wobei "name1" wohl besser einfach "name" wäre
if versender is None:
    versender = Adresse()
    versender.name1 = thename
    session.add(versender)

sendung = Sendung()
sendung.versender = versender
session.add(sendung)
session.commit()
Das selbe dann auch für den Empfänger.

Nebenbei, die Felder empf_id und vers_id sollten vom selben Typ sein wie die referenzierte Tabelle. String ist hier unangebracht, wenn die referenzierte Tabelle Integer ist.

Re: SqlAlchemy INSERT mit bereits vorhandenen ForeignKey

Verfasst: Donnerstag 27. März 2014, 10:22
von BlackJack
@python_hulk: Ergänzend zur letzten Bemerkung von Balmung: Man kann als Typ auch einfach `None` übergeben bei einem Fremdschlüssel, dann holt sich SQLAlchemy (SA) die Typinformation aus der anderen Tabelle.

Ich würde bei den Namen übrigens nicht so viel abkürzen und durchnummerieren. Lesbar ist was anderes. ;-)