Seite 1 von 4
Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 17:07
von meego
Warum stellen die DB-Macher die objektorientierte Funktionalität eigentlich nicht einfach selbst zur Verfügung? :K
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 17:09
von BlackJack
@meego: Welcher DB-Macher stellt denn dann genau was zur Verfügung? Die schaffen es ja nicht einmal SQL einheitlich anzubieten.
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 17:23
von meego
Gibt es keine objektorientiert ansprechbare Datenbank in der Welt? Oder wenigsten ein Tool dass das Schema in Pythoncode übersetzt?
SQLAlchemy scheint ziemlich kompliziert, aber ich werde mich weiter einlesen.. Immerhin konnte ich jetzt schon ein paar Datensätze in eine Tabelle schreiben. (Wenn auch erst bloss mit normalem SQL und ohne SQLAlchemy).
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 18:26
von BlackJack
@meego: Es gibt natürlich auch OOP-Datenbanken. Das sind dann aber eben keine SQL-Datenbanken. Und es gibt auch SQL-Datenbanken die selbst schon zumindest Ansätze einer OOP-Abstraktionsschicht bieten. Da hat dann aber jeder Hersteller der das macht sein eigenes Konzept.
Das Schema automatisch übersetzen kann man mit SQLAlchemy (SA) denn die Bibliothek bietet für die meisten DBMS auch ”reflection”. Da braucht kein Python-Code erzeugt zu werden, denn das passiert dynamisch zur Laufzeit. Allerdings möchte man beim ORM normalerweise selbst die Kontrolle haben wie, was abgebildet wird. Da kann man ja eine ganze Menge Feinheiten manuell einstellen und man möchte oft auch zusätzliche Funktionalität in die Modelle programmieren.
Selbst ohne das ORM ist SQLAlchemy nützlich um Unterschiede zwischen verschiedenen DBMS und DB-API V2 konformen Modulen auszubügeln.
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 18:51
von noisefloor
Hallo,
meego hat geschrieben:SQLAlchemy scheint ziemlich kompliziert, aber ich werde mich weiter einlesen.. Immerhin konnte ich jetzt schon ein paar Datensätze in eine Tabelle schreiben. (Wenn auch erst bloss mit normalem SQL und ohne SQLAlchemy).
SA scheint kompliziert, weil es mächtig ist - das Grundprinzip ist aber nicht wirklich kompliziert. Zumal die ja bei SA nicht zwingend den ORM-Teil nutzen musst. Du kannst ja z.B. auch "nur" das Connection Pooling benutzen, um die Verbindung zur SQL-DB herzustellen.
Der ORM von Django ist übrigens, zumindest für den Einsteig, IMHO viel simpler und für den Einstieg einfacher. Wobei SA AFAIK deutlich mächtiger ist - ob du das dann brauchst oder nicht musst du selber entscheiden
Gruß, noisefloor
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 19:01
von meego
Es führt also wohl kein Weg daran vorbei, die Tabellenklassen von Hand aufgrund vom Diagramm-Design abzutippen und dann hoffentlich nix zu vergessen.
@noisefloor: Kann man bei Django auch SA verwenden?
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 19:20
von noisefloor
Hallo,
Es führt also wohl kein Weg daran vorbei, die Tabellenklassen von Hand aufgrund vom Diagramm-Design abzutippen und dann hoffentlich nix zu vergessen.
Genau - du musst dein DB-Modell in Python abbilden.
@noisefloor: Kann man bei Django auch SA verwenden?
Du kannst innerhalb von Django natürlich auch andere Module verwenden als die von Django, wie z.B. ein anderes ORM oder eine andere Template-Engine. Ob das für dich Vorteile hat kannst nur du entscheiden.
Ein älterer, aber ganz guter Blogpost zu SA und Django ist z.B. im Blog von Armin Ronacher zu finden:
http://lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/.
Gruß, noisefloor
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 19:35
von meego
Hier ein Beispielscript zur Erstellung einer DB, welches ich im Web gefunden habe:
Code: Alles auswählen
import os
import sys
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import [b]declarative_base[/b]
from sqlalchemy.orm import [b]relationship[/b]
from sqlalchemy import create_engine
[b]Base = declarative_base()[/b]
class Person(Base):
__tablename__ = 'person'
# Here we define columns for the table person
# Notice that each column is also a normal Python instance attribute.
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
class Address(Base):
__tablename__ = 'address'
# Here we define columns for the table address.
# Notice that each column is also a normal Python instance attribute.
id = Column(Integer, primary_key=True)
street_name = Column(String(250))
street_number = Column(String(250))
post_code = Column(String(250), nullable=False)
person_id = Column(Integer, ForeignKey('person.id'))
[b]person = relationship(Person)[/b]
# Create an engine that stores data in the local directory's
# sqlalchemy_example.db file.
engine = create_engine('sqlite:///sqlalchemy_example.db')
# Create all tables in the engine. This is equivalent to "Create Table"
# statements in raw SQL.
Base.metadata.create_all(engine)
Was ist declarative_base()? Aus der
Doku werde ich noch nicht schlau. Die DB selber muss die Engine sein. Ist Base also einfach eine Art übergeordnetes Klammerobjekt für alle Alchemyklassen?
Warum die Beziehung irgendwie definiert werden muss, verstehe ich auch noch nicht (warum reicht der ForeignKey nicht?).
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 19:44
von Sirius3
@meego: irgendwo mußt Du doch angeben, dass person die Relationship zur Klasse Person ist. Und das Datenbankdesign mußt Du natürlich irgendwo eingeben, ob das nun als "CREATE TABLE" oder als Python-Klasse ist, ist doch egal, wobei Python-Klassen bequemer zu tippen sind.
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 20:03
von noisefloor
Hallo,
@meego: hast du das SQLAlchemy
Tutorial gelesen? Da ist im 3. Absatz erklärt, wozu `declarative_base()` gut ist.
Gruß, noisefloor
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 21:40
von meego
@sirius: Meine Überlegung war folgende: Da Column() ein Objekt von Alchemy ist, könnte es für Alchemy vielleicht möglich sein, den ForeignKey Python irgendwie im Hintergrund mitzuteilen. Aber die technischen Hintergründe sind mir unbekannt.
@Noisefloor: Noch nicht. Ich habe zwei andere Kurztutorials gelesen. Aber Danke für den Hinweis, das ist überraschend verständlich geschrieben.
Verwendet Ihr denn auch noch "__init__" für die Klassen?
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 21:53
von BlackJack
@meego: Das mit dem `ForeignKey` automatisch mitteilen habe ich nicht verstanden. Was sollte denn da Deiner Meinung nach automatisch passieren? Wie sollte der Name entstehen? Woher soll SA nur aus der `Column()` mit dem `ForeignKey` wissen um welche Art von Beziehung es sich handelt? Man will ja nicht immer so etwas simples wie ``person = relationship(Person)`` da stehen haben.
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 22:03
von DasIch
Aus dem ForeignKey selbst ist nicht zu ermitteln ob dies eine One-To-One oder Many-To-One Beziehung ist. Bei einer Many-To-One Beziehung ist es nicht möglich zu ermitteln welche Datenstruktur verwendet werden soll: Liste, set, irgendwas anderes?
relationship() erlaubt dir diese Informationen die das Schema nicht beschreiben kann, SQLAlchemy mitzuteilen.
Re: Warum braucht es SQLAlchemy?
Verfasst: Samstag 11. Juli 2015, 22:29
von meego
So wie ich es verstanden habe, kann eine Person mehrere Adressen haben (da der ForeignKey in der Adresstabelle liegt). Über den ForeignKey könnte man dann immer den Namen der Person ermitteln. Falsch?
Das mit Liste + Dictionary habe ich nicht verstanden.
Re: Warum braucht es SQLAlchemy?
Verfasst: Sonntag 12. Juli 2015, 14:33
von Sirius3
@meego: richtig. Aber viele Abhängigkeitsvarianten lassen sich in einer Hochsprache viel präziser ausdrücken. Den Unterschied zwischen einer 1:1- oder einer 1:n-Beziehung lassen sich mit Foreign-Keys alleine nicht ausdrücken. Du willst eine 1:n-Beziehung haben, in anderen Tabellen ist das vielleicht anders.
Re: Warum braucht es SQLAlchemy?
Verfasst: Montag 13. Juli 2015, 09:41
von meego
Ich habe mal etwas zusammen gecoded. Die User können sich Nachrichten schicken. Wie wäre die Beziehung hier zu definieren? Sonstige Kritik?:
Code: Alles auswählen
import os
import sys
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlaclhemy import create_engine
Base = declarative_base
#datenbankblaupausen
class User(Base):
__tablename__ = 'user'
#Columns for the table user
id = Column(Integer, primary_key=True)
vorname = Column(String(80), nullable=False)
name = Column(String(80), nullable=False)
email = Column(String(80), index=True, nullable=False)
strasse = Column(String(80), nullable=False)
plz = Column(String(80), nullable=False)
ort = Column(String(80), nullable=False)
password_hash = Column(String(500), nullable=False)
salt = Column(String(250), nullable=False)
id_messages = Column(Integer, ForeignKey('message.id'))
class Messages(Base):
id = Column(Integer, primary_key=True)
zeitstempel = Column(TIMESTAMP, nullable=False)
gelesen = Column(Boolean, nullable=False)
betreff = Column(String(250), nullable=False)
text = Column(String, nullable=False)
Re: Warum braucht es SQLAlchemy?
Verfasst: Montag 13. Juli 2015, 10:53
von BlackJack
@meego: Ich würde mal sagen das funktioniert so nicht. Schreib doch mal ein paar konkrete Datensätze auf ein Blatt Papier (oder in eine Textdatei) mit sagen wir mal zwei Benutzern die sich gegenseitig ein paar Nachrichten geschickt haben.
Re: Warum braucht es SQLAlchemy?
Verfasst: Montag 13. Juli 2015, 11:10
von noisefloor
Hallo,
jeder User kann N Messages schicken und jede Message hat genau einen (1) User (=Absender) und einen (?) Empfänger. Das spiegelt dein Entwurf nicht wieder.
Gruß, noisefloor
Re: Warum braucht es SQLAlchemy?
Verfasst: Montag 13. Juli 2015, 13:44
von meego
Hallo. Ist es so besser?:
Code: Alles auswählen
class User(Base):
__tablename__ = 'user'
#Columns for the table user
id = Column(Integer, primary_key=True)
vorname = Column(String(80), nullable=False)
name = Column(String(80), nullable=False)
email = Column(String(80), index=True, nullable=False)
strasse = Column(String(80), nullable=False)
plz = Column(String(80), nullable=False)
ort = Column(String(80), nullable=False)
password_hash = Column(String(500), nullable=False)
salt = Column(String(250), nullable=False)
id_messages = Column(Integer, ForeignKey('message.id'))
class Messages(Base):
id = Column(Integer, primary_key=True)
zeitstempel = Column(TIMESTAMP, nullable=False)
empfaenger = Column(Integer, ForeignKey('user.id'))
sender = Column(Integer, ForeignKey('user.id'))
gelesen = Column(Boolean, nullable=False)
betreff = Column(String(250), nullable=False)
text = Column(String, nullable=False)
Re: Warum braucht es SQLAlchemy?
Verfasst: Montag 13. Juli 2015, 14:21
von jerch
@meego:
fast richtig - das `id_messages = Column(Integer, ForeignKey('message.id'))` in User macht keinen Sinn, statt dessen ist es sinnvoll, in User 2 (Rück-)Relationen anzulegen - eine für empfangene und eine für gesendete Nachrichten.