zusätzliche Informationen anhand des Feld-Namens

Django, Flask, Bottle, WSGI, CGI…
Antworten
paddie
User
Beiträge: 100
Registriert: Donnerstag 11. Oktober 2018, 18:09

Ich weiß gar nicht ob das jetzt besser hier hin passt oder eher in das Datenbank Subforum.


Meine Produkt-Daten in meinem Django-Projekt sollen jetzt nach etim-bmecat exportiert werden. Zusätzlich sollen die Produkte auch nach ETIM klassifiziert werden. Dafür wird jedes Produkt einer bestimmten Klasse zugeordnet z. B. Wand- und Deckenleuchten wäre Klasse EC002892. Das ist jetzt kein Problem, das ist nur ein zusätzliches Feld bzw. Tabelle in der DB ;-).

Mein Problem jetzt: Die einzelnen Eigenschaften des Produkts bekommen auch jeweils einen eigenen Code. So bekommt der Lichtstrom (bei mir in der Datenbank auf zwei Felder aufgeteilt luminous_flux_min und luminous_flux_max) im ETIM-System dann den Code EF009349. Mir fehlt allerdings eine Idee wie ich eine ordentliche Zuweisung zwischen der jeweiligen Eigenschaft und dem Featurecode hinbekomme

Das einzige was mir eingefallen ist, dass ich eine separate Tabelle erstelle in der ich zu jedem Feldnamen einen Eintrag mit dem jeweiligen Featurecode habe. Dann würde ich mit getattr den Feldnamen "ermitteln" und dann eben in der Tabelle suchen. Da es sich hier (bis jetzt) nur um ca. 30 - 40 Codes handelt wäre der Aufwand (auch bei Änderungen) noch halbwegs erträglich.

Gibts vielleicht eine bessere Lösung?

Danke schonmal
Benutzeravatar
sparrow
User
Beiträge: 4119
Registriert: Freitag 17. April 2009, 10:28

Das klingt, als müsste die Eigenschaft ein Objekt sein dass den Code als Feld hat. Oder über eine 1:n Beziehung mehrere Codes.

Wenn man Feldnamen dynamisch ermitteln muss, ist das oft ein Warnzeichen für kaputtes Design.
paddie
User
Beiträge: 100
Registriert: Donnerstag 11. Oktober 2018, 18:09

Hmmm...Aber ich hab ja nicht nur einen Datentyp.. Wenn alles z. B. Integer wären also ungefähr so was in der Art:

Code: Alles auswählen

class ProductProperty(models.Model):
    text = models.CharField()
    value = models.IntegerField()
    feature_code = models.CharField()
In der jeweiligen Klasse mach ich dann ein

Code: Alles auswählen

class Product(models.Model):
    ...
    luminous_flux = models.ForeignKey(ProductProperty, ....)
    ...
Oder hab ich dich jetzt falsch verstanden.
Wie oben schon geschrieben hab ich aber auch andere Datentypen... :wink: . Dann müsste ich ja auch für jeden Datentyp eine eigene Tabelle erstellen :?
Bei meinem vorherigen "Problem" mit den verschiedenen Dateitypen war das ja noch recht einfach ;-). Aber hier :?
Benutzeravatar
sparrow
User
Beiträge: 4119
Registriert: Freitag 17. April 2009, 10:28

Und wenn es 200 verschiedene Eigenschaften gibt, das legst du 200 Felde dafür an? Das klingt komisch.

Das was hier erklärt ist, umfasst ja nur einen Teil des Problems, aber so wie ichd as verstehe würde ich gar kein Feld für die Eigenschaften im Product haben sondern eine Zwischtabelle für den Wert.

Symbolcode:

Code: Alles auswählen

class Property(models.Model):
    name = models.CharField
    code = models.CharField
    # Möglichkeiten den "Typ" zu prüfen, falls das nötig ist:
    # valueType = `choices of types`
    # regex = models.CharField (

class ProductProperty(models.Model):
    product = models.ForeignKey("Product")
    property = models.ForeignKey("Property")
    value = models.CharField()

class Product(models.Model):
    ...
paddie
User
Beiträge: 100
Registriert: Donnerstag 11. Oktober 2018, 18:09

OK, ich glaube grob zu verstehen...teilweise ;-).
Ich verstehe aber immernoch nicht wie ich dann die verschiedenen Typen abbilde?!
Oder speicher ich einfach alles als Char und wenn ich die Daten dann weiterverarbeiten will greif ich auf den "valueType" zurück und wandle die Daten dann entsprechend um? Genauso dann Date(Time)Fields. Am Ende hätte ich also "nur noch" meine ForeignKey oder ManyToMany Felder in der Klasse und der Rest würde in der Property Klasse landen?

Danke schonmal bis hierhin..
Benutzeravatar
sparrow
User
Beiträge: 4119
Registriert: Freitag 17. April 2009, 10:28

Da gibt es verschiedene Möglichkeiten.

Du könntest den "type" in einem Feld speichern und dann zum Beispiel in einer Property doe Konvertierung durchführen. Das macht aber zum Beispiel nur Sinn, wenn ud auf Datenbankebene nie mit den Daten arbetien willst. Also wenn es nur um eine Validierung geht.

Sollte man das doch auf Datenbanklevel brauchen, dann könnte man je Typ eine Property anlegen.

Last but not least:
Je Typ ein Feld.

Kann man ohne das Projekt zu kennen schwierig beantworten.

Code: Alles auswählen

class Property(models.Model):
    name = models.CharField
    code = models.CharField
    # Möglichkeiten den "Typ" zu prüfen, falls das nötig ist:
    # valueType = `choices of types`
    # regex = models.CharField (

class ProductProperty(models.Model):
    product = models.ForeignKey("Product")
    property = models.ForeignKey("Property")
    char_value = models.CharField()
    int_value = models.IntField()
    datetime_value = models.DateTime()
    
    @property
     def value(self):
        if self.property.type == "Integer":
            return self.int_value
        ....

class Product(models.Model):
    ...
Vielleicht kann man _da_ dann auch magisch die Werte aus den Feldern holen, aber in dem ORM steckt schon so viel Magie, dass das kaputt gehen könnte.
Müsste mane in bisschen probieren.
paddie
User
Beiträge: 100
Registriert: Donnerstag 11. Oktober 2018, 18:09

So wie es aussieht müsste ich dann wohl mein gesamtes model umbauen :?.

Bis jetzt ist eben alles über einige Klasse/Tabellen verteilt (Datenbank besteht jetzt aus ca. 60 Tabellen...ohne die von Django-eigenen). Das heisst, dass die Felder, denen ein Featurecode zugeordnet werden soll über diese Klassen verstreut liegen und sich imho auch nur schwer "enger" zusammenfassen lassen. Die Klassifizierung war bis letzte Woche auch noch nicht relevant bzw. mir komplett unbekannt.
Das jetzt alles SO umzubauen, dass die vorherige Funktionalität bestehen bleibt UND die Codezuordnung so funktioniert wie es soll übersteigt mein Können dann scheinbar doch um einiges...Also werd ich dieses Teilprojekt wohl als gescheitert erklären

Trotzdem vielen Dank für deine Hilfe
Benutzeravatar
sparrow
User
Beiträge: 4119
Registriert: Freitag 17. April 2009, 10:28

60 Tabellen zu haben ist nicht unbedingt ungewöhnlich.
60 Modelle zu haben, könnte der Hinweis darauf sein, dass bei der Normalisierung etwas grundsätzlich schief gegangen ist. Ein oft gemachter Fehler: Man denkt wie in einer Tabellenkalkulation. Oft wird man dazu verleitet, weil das Wort "Tabelle" bzw. "Table" verwendet wird. Dabei heißt die Tabelle in einer Tabellenkalkulation "Sheet".

Falls du dich fragst, ob du die Normalform deiner Daten gefunden hast (der Thread deutet auf Nein hin): der Wikipedia Artikel zur Normalisierung ist wirklich gut.
paddie
User
Beiträge: 100
Registriert: Donnerstag 11. Oktober 2018, 18:09

Für mich war bisher eine Model Klasse auch immer 1 table in der Datenbank. zzgl natürlich noch die jeweiligen join-tables für Many-to-Many. Der Unterschied zwischen einer Tabellenkalkulation und einer Datenbank ist mir schon klar ;-) und ich dachte bisher eigentlich ich hätte halbwegs auf die Normalisierung aufgepasst ;-).

Ich hab übrigens etwas übertrieben. Im Groben sind alle benötigten Daten auf mein "Product" Model und dessen Kind-Klassen aufgeteilt. Einige zusätzliche Daten (die halt eben nicht direkt in die "Product"-Klasse gehören) sind dann in separaten Klassen. Nachdem was ich sonst so im Netz gefunden hab imho nichts ungewöhnliches ;-).
Antworten