Seite 1 von 1
SQLAlchemy: Attribut als Klasse
Verfasst: Mittwoch 4. August 2010, 09:17
von frabron
Hallo,
irgendwie bin ich zu doof, etwas entsprechendes in der SQLAlchemy - Doku zu finden:
Ich möchte ein Attribut einer SQLAlchemy Klasse nicht als Wert aus der DB repräsentieren, sondern als eigenständige Klasse, allerdings nicht als weitere SQLAlchemy Klasse ...
sowas in der Art:
Code: Alles auswählen
class Weight(object):
# spannende Klasse zum Umrechnen von Gewichten
pass
# Persistenz
class Person(Base):
id = Column(Integer, primary_key=True)
weight = Column(Numeric)
hier wird ja das Gewicht der Person als Zahlenwert aus der DB gelesen. Ich suche jetzt einen Mechanismus, der mir das Gewicht nicht als Wert sondern als eigene Klasse einsetzt. Das muss ja sowohl beim Lesen, als auch beim Speichern wieder in den Zahlenwert umgewandelt werden. Weiss jemand, wie man sowas realisieren könnte? Privates, numerisches Attribut und das öffentliche Attribut, welches die Klasse hält, über getter/setter?
Frank
Re: SQLAlchemy: Attribut als Klasse
Verfasst: Mittwoch 4. August 2010, 10:00
von EyDu
Hallo.
Suchst du
das?
Sebastian
Re: SQLAlchemy: Attribut als Klasse
Verfasst: Donnerstag 5. August 2010, 08:09
von frabron
Hallo Sebastian,
ja, das scheint eine Möglichkeit zu sein, so etwas umzusetzen. Leider ist die Dokumentation dazu nicht ganz vollständig - da hilft wohl nur ausprobieren ...
Gruß
Frank
Re: SQLAlchemy: Attribut als Klasse
Verfasst: Mittwoch 11. August 2010, 13:26
von frabron
So gehts:
Code: Alles auswählen
# coding: utf-8
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.types import TypeDecorator, Numeric
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Weight(object):
def __init__(self, value, unit):
self.value = value
self.unit = unit
@property
def base_value(self):
return self.value * 1000
class WeightType(TypeDecorator):
impl = Numeric
def process_bind_param(self, weight, dialect):
return weight.base_value
def process_result_value(self, value, dialect):
return Weight(value, "g")
class Person(Base):
__tablename__ = 'persons'
id = Column(Integer, primary_key=True)
name = Column(String)
weight = Column(WeightType)
def __init__(self, name, weight):
self.name = name
self.weight = weight
def setup_database():
engine = create_engine('sqlite:///memory', echo=True)
Session = sessionmaker(bind=engine)
session = Session()
return engine, session
def save():
engine, session = setup_database()
Base.metadata.bind = engine
Base.metadata.create_all()
peter = Person("Peter", Weight(70, "kg"))
karl = Person("Karl", Weight(80, "kg"))
jutta = Person("Jutta", Weight(65, "kg"))
session.add_all([peter, karl, jutta])
session.commit()
def load():
engine, session = setup_database()
Base.metadata.bind = engine
Base.metadata.create_all()
peter = session.query(Person).filter(Person.name=="Peter").first()
print peter.name, peter.weight.value
if __name__ == "__main__":
save()
load()