SqlAlchemy INSERT mit bereits vorhandenen ForeignKey

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
python_hulk
User
Beiträge: 5
Registriert: Dienstag 11. März 2014, 08:54

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
Benutzeravatar
Balmung
User
Beiträge: 44
Registriert: Sonntag 17. März 2013, 18:36

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.
»Honk Honk«
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. ;-)
Antworten