Relationen in SQLALchemy + hinzufügen eines Datensatz

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
mt-fritzschi
User
Beiträge: 4
Registriert: Mittwoch 12. März 2014, 13:56
Wohnort: Jena

Hallöle,
hab leider ein Problem ich wollte SQLALchemy nutzen auf eine vorhandene MySQL Datenbank zuzugreifen.
Vielleicht erstmal kurz zur Eigentlichen Datenbank (Prozesse werden abgelegt) 1 Prozess besteht aus mehreren Schritten die aus verschiedenen Elementen bestehen

Tabelle Prozess (Prozess_ID, Schritt_ID)
Tabelle Schritte (Schritt_ID (Autoincrement), Handelnder_id, Zeit)
Tabelle Handelnder (Handelnder_id, Name)

Prozess_ID | Schritt_ID | Handender | Zeit
123 | 1 | Meyer | 22
123 |2 | Müller |

In etwa so soll die Tabelle wenn sie zusammengeführt aussehen
Verbindung zur Datenbank hab ich erfolgreich aufgenommen.

Dann hab ich die MetaData Instanz für die Tabellen festgelegt :

Code: Alles auswählen

Prozess_table=Table('prozess', MetaData,autoload=True)
Schritt_table=Table('schritt', MetaData,autoload=True)
Handelnder_table=Table('handelnder', MetaData,autoload=True)
Die Klassen Angelegt nach dem Muster:

Code: Alles auswählen

class Prozess(object):
    def __int__(self,prozess_id,schritt_id):
        self.prozess_id=prozess_id
        self.step_id=step_id
Bis hierhin bin ich mir auch noch relativ Sicher das alles Stimmt aber dann kommt das mapping und die Relationen:

Code: Alles auswählen

orm.mapper(Handelnder,handelnder_table,properties=
        dict(Schritte=orm.relation(Schritte,uselist=False,backref='handelnder'))

Code: Alles auswählen

orm.mapper(Schritte,schritte_table)

Code: Alles auswählen

orm.mapper(Prozess,prozess_table,properties=
        dict(schritte=orm.relation(Schritte,uselist=False,backref='prozess')))
Meine Fragen
1. Hab die die relationen richtig gesetzt oder hab ich mich doch vertan?
EIne Fehlermeldung das was am Code Falsch wäre bekomme ich nicht (noch nicht), ich vermute eben nur das er die Relationen nicht so baut wie sie sein sollten und ich deswegen auch keinen Ansatz finde einen Datensatz hinzuzufügen :?: :?: :?:

Und
2. Wie bewerkstellige ich denn das Hinzufügen eines neues Datensatzes? :K


Wäre Tipps und Hilfestellung sehr Dankbar irgendwie fehlen mir da zwei drei Windungen um dahinter zu kommen.
Benutzeravatar
Balmung
User
Beiträge: 44
Registriert: Sonntag 17. März 2013, 18:36

Es ist in der Regel einfacher die deklarative Schreibweise zu verwenden:
http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html

und dann zu Relationen:
http://docs.sqlalchemy.org/en/rel_0_9/o ... ships.html
»Honk Honk«
mt-fritzschi
User
Beiträge: 4
Registriert: Mittwoch 12. März 2014, 13:56
Wohnort: Jena

Hey,

danke für die antwort. Hut werd ich mal sehen ob es so logischer wird :) Man lernt ja nie aus :D
mt-fritzschi
User
Beiträge: 4
Registriert: Mittwoch 12. März 2014, 13:56
Wohnort: Jena

Grüße,

muss leider nochmal fragen -.-

Ich habe wie empfohlen den Declarativen Weg genommen und nochmal alles nach Anleitung geschrieben, und scheint auch soweit i.O. zu sein.

Code: Alles auswählen

from sqlalchemy import create_engine
from sqlalchemy import Column, Integer,Table, String, ForeignKey,MetaData
from sqlalchemy.orm import relationship,backref
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import  declarative_base

try:
	engine=create_engine("mysql+mysqlconnector://***:******@localhost/test")
except:
	print ('No Connection')
	

Basis = declarative_base()


class Prozess (Basis):
	__tablename__='prozess'
	prozess_id=Column(Integer, primary_key=True)
	schritt_id=Column(Integer,ForeignKey('schritt.schritt_id'))
	schritt= relationship("Schritt", backref=backref('Prozess'))
	
class Schritt(Basis):
	__tablename__='schritt'
	schritt_id=Column(Integer,primary_key=True)
	akteur_id=Column(Integer,ForeignKey('akteur.akteur_id'))
	massnahme_id=Column(Integer,ForeignKey('massnahme.massnahme_id'))
	akteur = relationship("Akteur", backref=backref('Schritt'))
	massnahme = relationship("Massnahme", backref=backref('Schritt'))
	
class Akteur(Basis):
    __tablename__='activity'
    akteur_id=Column(Integer,primary_key=True)
    akteur_name=(String)
	
class Massnahme(Basis):
    __tablename__='actor'
    massnahme_id=Column(Integer,primary_key=True)
    massnahme_name=(String)
	

Table ('Schritt',MetaData(bind=None),
            Column('Schritt_id',Integer(),primary_key=True,nullable=False),
            Column('massnahme_id',Integer(),nullable=False),
            Column('akteur_id',Integer(),nullable=False),


Table ('massnahme',MetaData(bind=None),
		Column('massnahme_id',Integer(),primary_key=True,nullable=False),
		Column('massnahme_name',String(100)))
		
Table ('akteur',MetaData(bind=None),
		Column('akteur_id',Integer(),primary_key=True,nullable=False),
		Column('akteur_name',String(100)))



# Beginn Daten in Db übertragen		
Session = sessionmaker(bind=engine)
neuesitzung=Session()

newprozess=Prozess(prozess_id=666)
newakteur=Akteur(Akteur_name='benno')
newmassnahme=Massnahme(massnahme_name='tut was')
neuesitzung.add_all([newprozess,newakteur,newmassnahme])

newschritt=Schritt(akteur_name='newakteur',massnahme_name='newmassnahme')

neuesitzung.add(newschritt)

neuesitzung.commit()

Wenn ich allerdings jetzt Versuche Daten in die Datenbank zu schieben bekomm ich einen fehler :

Cannot add or update a child row: a foreign key constraint fails (test.Prozess, CONSTRAINT Fk_prozess_schritt FOREIGN KEY (schritt_id) REFERENCES schritt (schritt_id))

Die Fremdschlüssel sind meiner Meinung nach richrtig anglegt und in der Datenbank auch vorhanden -.-


Kann mir einer sagen wo ich mich hier vertan habe ???
BlackJack

@mt-fritzschi: Du verwechselst hier Namen in Python für Objekte und Zeichenketten die diese Namen enthalten. Und die Reihenfolge stimmt nicht. Wenn ein Prozess einen Schritt braucht, dann sollte man natürlich erst den Schitt erzeugen, denn den muss man beim Erstellen vom Prozess ja angeben. Das dann natürlich weiter bei Akteur und Massnahme.

Das ``try``/``except`` am Anfang macht keinen Sinn. Lass das einfach weg.
mt-fritzschi
User
Beiträge: 4
Registriert: Mittwoch 12. März 2014, 13:56
Wohnort: Jena

Ja stimmt das is natürlich Logisch mit der Reihenfolge -.- manchmal sieht man den Wald nicht mehr -.-

Danke :)
Antworten