Seite 1 von 1
Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 11:36
von sonovice
Hallo z'ammen,
ich arbeite mich gerade ein wenig in ORM mit SQLAlchemy ein und stehe vor folgendem Problem:
Es existiert eine Klasse "Mikrofon", die folgende SQL-Spalten enthalten soll:
- Hersteller
- Typbezeichnung
- Richtcharakteristik
Leider gibt es Mikrofone, die umschaltbare Richtcharakteristiken bereitstellen. Wie könnte man soetwas geschickt und "ORM-mäßig" verpacken? "List" wird als Datentyp offensichtlich nicht von SQLAlchemy unterstützt.
Ich befürchte, dass das eine völlige Grundlagenfrage ist, aber es ist schwierig, nach vernünftigen Stichworten diesbezüglich zu googlen...
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 11:50
von Hyperion
Das hat imho erst einmal nichts mit dem ORM zu tun, sondern eher mit der grundlegenden *relationalen* Modellierung.
Wenn ich das richtig verstehe, bilden "Hersteller" und "Typbezeichnung" einen PK, um ein Mikrofon zu definieren. Nun haben aber nicht alle Mikrofone nur *einen* Wert "Richtercharacteristik", sondern theoretisch beliebig viele? Richtig?
Diese Charakteristiken sind für jedes Mikrofon genommen dann eindeutig? Wenn ja, könntest Du einfach die Charakteristik zusätzlich in Deinen PK aufnehmen, um eine eindeutig identifizierbaren Datensatz zu schaffen. Wenn Du dann eine Query nur über "Hersteller" und "Typ" als Bedingung durchführst, erhältst Du einfach alle Charakteristiken eines Modells.
Allerdings ist dann die Frage, ob noch anderen, einzigartige Datensätze pro Mikrofon hinzukommen... wenn ja, sollten diese schon in eine separate Tabelle ausgelagert werden. Denn sonst hast Du Redundanzen in Deinem Modell. Sprich, eine Tabelle "Produkt" und eine "Charakterisken". In ersterer stehen nur die einzigartigen Eigenschaften eines Mikrofons, in der zweiten nur diese "Richtercharakteristiken" (ergo das, was ich im Absatz zuvor beschrieben habe

)
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 15:16
von sonovice
Vielen Dank für deine Antwort. Ich versuche mal, das etwas präziser zu formulieren:
In der Welt der Musikaufnahme gibt es nur eine handvoll sinnvoller
Richtcharakteristika:
- Niere
- Breite Niere
- Superniere
- Hyperniere
- Kugel
- Acht
- Keule
Einem Mikrofon kann entweder nur eine dieser 7 Optionen zugeordnet sein oder eben mehrere.
Funktional soll am Ende eine Datenbank herauskommen, die sich sowohl nach Hersteller als auch Charakteristik filtern lassen soll. Ich hätte jetzt als PK einfach eine ID verteilt, die Hersteller als eigene Tabelle mit entsprechender Relation zu den Mikros gemacht und den Typen als einfache String-Column. Nur bei den Charakteristiken bin ich mir unschlüssig...
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 15:40
von BlackJack
@sonovice: Das könnte man auf diese Tabellen runterbrechen:
Code: Alles auswählen
hersteller (id serial, name text)
mikrofon (id serial, hersteller_id integer, typ text)
richtcharakteristika (id serial, name text)
mikrofon_charakteristika (mikrofon_id integer, richtcharakteristika_id integer)
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 15:45
von sonovice
BlackJack hat geschrieben:@sonovice: Das könnte man auf diese Tabellen runterbrechen [...]
Oh man, ich sollte wegkommen von meinem reinen "Klassendenken" und noch ein paar Nachhilfestunden in relationalen Datenbanken nehmen... Vielen Dank, so ergibt das natürlich erstaunlich einfach Sinn.
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 17:29
von sonovice
So, nur um kurz sicherzustellen, dass ich keinen Unfug baue und später Stunden zum Debuggen vergehen:
Ist folgendes korrekt?
Code: Alles auswählen
class Manufacturer(Base):
__tablename__ = 'manufacturer'
id = Column(Integer, primary_key=True)
name = Column(String)
class Directivity(Base):
__tablename__ = 'directivity'
id = Column(Integer, primary_key=True)
name = Column(String)
class Microphone(Base):
__tablename__ = 'microphone'
id = Column(Integer, primary_key=True)
manufacturer_id = Column(Integer, ForeignKey('manufacturer.id'))
comment = Column(String)
class MicrophoneDirectivity(Base):
__tablename__ = 'microphone_directivity'
id = Column(Integer, primary_key=True)
microphone_id = Column(Integer, ForeignKey('microphone.id'))
directivity_id = Column(Integer, ForeignKey('directivity.id'))
Besonders der PK ganz am Schluss bereitet mir noch etwas Kopfzerbrechen. Und fehlen nicht noch Relationen, um z.B. nach Hersteller bzw. Charakteristik zu filtern?
EDIT: Thema backreferences - Die hab' ich komplett weggelassen, merke ich gerade...
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 19:39
von BlackJack
Das letzte würde man nicht durch eine Klasse modellieren, denn es ist ja eigentlich nur die Verbindung zwischen zwei Tabellen. Schau Dir mal das hier an:
http://docs.sqlalchemy.org/en/rel_0_8/o ... ny-to-many
Re: Listen in SQLAlchemy
Verfasst: Samstag 23. Februar 2013, 21:15
von sonovice
Okay, also hier meine Überarbeitung:
Code: Alles auswählen
microphone_directivity_association = Table('association', Base.metadata,
Column('microphone_id', Integer, ForeignKey('microphone.id')),
Column('directivity_id', Integer, ForeignKey('directivity.id')))
class Manufacturer(Base):
__tablename__ = 'manufacturer'
id = Column(Integer, primary_key=True)
name = Column(String)
microphones = relationship('Microphone', backref='manufacturer')
def __init__(self, name):
self.name = name
class Microphone(Base):
__tablename__ = 'microphone'
id = Column(Integer, primary_key=True)
name = Column(String)
comment = Column(String)
manufacturer_id = Column(Integer, ForeignKey('manufacturer.id'))
directivities = relationship('Directivity',
secondary=microphone_directivity_association,
backref='microphones')
def __init__(self, name, comment=''):
self.name = name
self.comment = comment
class Directivity(Base):
__tablename__ = 'directivity'
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
Falls noch Schnitzer drin sein sollten, würde ich mich über Kritik freuen.