SQLObj. in eigener Klasse / Methoden per Schleife erzeugen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
moesibaer
User
Beiträge: 16
Registriert: Donnerstag 27. Dezember 2007, 15:54
Kontaktdaten:

Montag 24. März 2008, 21:15

Hallo zusammen!

Für meine Webanwendung verwende ich SQLObjekt. Da es mich genervt hat, jeden Wert vor der Übergabe mit SQLObjekt zur Datenbank zu überprüfen, wollte ich nun das SQLObjekt in meiner eigenen Klasse kapseln und für jedes Datenbankfeld einen Setter und Getter mit property erzeugen.

Etwa so habe ich mir das gedacht

Code: Alles auswählen

from mytables import User
class User():

    def __init__(self):
        self._obj = None
        self._table = User

    def get(self,value=None):
        if value is None:
            raise AttributeError("No values for userobject have been supplied")
        
        try:
            if isinstance(value,int):
                self._obj = self._table.get(value)
            if isinstance(value,basestring):
                self._obj = self._table.selectBy(name=value)[0]
        except SQLObjectNotFound:
            raise ObjectNotFound("%s could not be found" % self._name)
        except IndexError:
            raise ObjectNotFound("%s could not be found" % self._name)
    
        if self._obj is None:
            raise ObjectNotFound("%s could not be found" % self._name)


    def Gname(self):
        return self._obj.name

    def Sname(self,value=None):
        #
        #hier ein paar Überprüfungen des Wertes
        #
        self._obj.name = value

    name = property(Gname,Sname)

#beispiel
User.get(1) #hole den Benutzer mit der ID 1
User.name = "admin" # Änder seinen Namen auf "admin"
Soweit die Idee. Jetzt hab ich allerdings ca. 8 Tabellen mit zwischen 10-30 Spalten, die ich alle als Getter und Setter in meiner Klasse erstellen müsste. DIe meisten Felder sollen durch meine Klasse jedoch gesperrt werden

Code: Alles auswählen

def Gblub(self):
    return self._obj.blub

def Sblub(self,*args,**keywd):
    raise DoNotChange("Wert darf nicht verändert werden")

blub = property(Gblub,Sblub)
Um mir einiges an Arbeit zu ersparen und vor allem die Klasse dynamisch aktuell zu halten, wenn ich mal meine tables.py ändere, möchte ich diese Methoden in einer Schleife erzeugen und der Klasse anhängen. Die Schleife sollte dabei z.B. die Attribute des SQLObjekt durchlaufen. für die Attribute, bei dennen ich Änderungen zulassen möchte, würde ich die Methode dann einfach überschreiben.

Jemand eine Idee wie ich das realisieren könnte mit der Schleife, oder hat jemand vielleicht sogar eine bessere Idee dafür?

Danke für jede Hilfe!
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 24. März 2008, 21:18

Ich würde an dieser Stelle Metaklassen ausprobieren. Musst dir dann eben die Dokumentation dazu durchlesen und etwas kombinieren.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
moesibaer
User
Beiträge: 16
Registriert: Donnerstag 27. Dezember 2007, 15:54
Kontaktdaten:

Montag 24. März 2008, 21:29

In wie weit helfen mir MetaKlassen dabei diese Methoden automatisch zu erzeugen? Kann ich den dem SQLObjekt einfach eine Meta Klasse hinzufügen ohne dessen Funktionalität zu verändern bzw. zu gefährden?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 24. März 2008, 23:14

moesibaer hat geschrieben:In wie weit helfen mir MetaKlassen dabei diese Methoden automatisch zu erzeugen?
Beim Erstellen deiner User-Klasse musst du eben via Introspection gucken, welche Methoden du hinzufügen musst und fügst diese eben hinzu. Quasi Codegenerierung zur Laufzeit :)
moesibaer hat geschrieben:Kann ich den dem SQLObjekt einfach eine Meta Klasse hinzufügen ohne dessen Funktionalität zu verändern bzw. zu gefährden?
Die Klasse die du im Beispiel zeigst ist eine ganz normale old-style Klasse, da hat SQLObject keine speziellen Hooks.

In Djangos ORM ist das hingegen etwas komplizierter, da sie ja von Djangos ORM-Klassen erben und somit da einiges an Meta-Magie machen, aber dennoch ist so etwas machbar.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Dienstag 25. März 2008, 09:00

moesibaer hat geschrieben:In wie weit helfen mir MetaKlassen dabei diese Methoden automatisch zu erzeugen?
Properties sind in Python immer an eine Klasse gebunden. Du kannst also nicht eine Instanz erzeugen und dann exklusiv für diese Instanz ein Property erzeugen. Das Property wäre automatisch in allen Instanzen derselben Klasse vorhanden, was du ja nicht willst, oder?

Du musst also für jede Instanz, die du erzeugen möchtest, eine eigene Klasse erstellen. Mit Metaklassen kannst du das steuern. Ich selbst habe bei was ähnlichem keine Metaklassen verwendet, sondern in __new__ eine entsprechende Klasse abgeleitet, erzeugt und instanziert.
Kann ich den dem SQLObjekt einfach eine Meta Klasse hinzufügen ohne dessen Funktionalität zu verändern bzw. zu gefährden?
Das würde ich nicht machen. Bastel dir eine Klasse, die einfach den Proxy zu deinem SQLObject spielt. Dann darf auch eine zukünftige Version von SQLObject selbst Metaklassen benutzen, ohne dass du an deinem Code wieder basteln musst.

Auf Properties könntest du auch komplett verzichten, wenn du z. B. generische Getter und Setter erzeugst und dann mittels __getattr__ und __setattr__ Properties simulierst.

Gruß,
Manuel
Antworten