Seite 1 von 1
Mit SQlite Objekte speichern, was bringt das eigentlich ?
Verfasst: Samstag 8. August 2009, 19:29
von ippurk
Hallo mal wieder,
bezüglich meiner Miethausverwaltung (aktuelle Version (auch noch ziemlich unterentwickelt) liegt
hier) suche ich nach einer Möglichkeit, vom Nutzer angelegte Daten auch dauerhaft und sicher speichern zu können. Nach einer etwas krampfigen Einarbeit in sqlite funktioniert mein Testskript (
hier) auch endlich ungefähr so, wie ich mir das vorstelle.
Nur, später gibts ja ungefähr zigmillionen Objekte, Blumen oder Mieter, was auch immer. Wenn ich dann aber sowas anfragen will, wie "alle Mieter anzeigen, die zu spät Miete gezahlt haben" muss ich ja, um auf die entsprechenden Eigenschaften der gespeicherten Objekte zugreifen zu können, sämtliche Datenbankeinträge erst mal in Objekte umwandeln, um dann in denen wiederum nach den gefragten Eigenschaften zu suchen.
Das würde doch aber für eine relativ hohe Speicherbelastung sorgen und kommt mir auch irgendwie unsinnig vor.
Dazu kommt auch noch, daß z.B. mein "Wohnung"-Objekt eine Liste aller jemals eingezogenen Mieter enthält, welche man ja wieder nur über Umwege in der DB abspeichern könnte.
Jetzt aber nur direkt mit Datenbankeintragungen zu arbeiten, finde ich dann auch wieder inkonsequent, ich will doch meine tollen Methoden benutzen (siehe Miethauscode), wie z.B. "Mieter in Wohnung einziehen lassen".
Ich weiß grad irgendwie nicht, in welche Richtung ich jetzt weitergehen soll. Mein Datenbankansatz kommt mir nicht schlüssig vor. Meine Miethausverwaltung aber wenigstens son bißchen. Oder sollte ich letztere unter dem Aspekt der Datenspeicherung besser völlig anders aufbauen ? Wie macht man sowas ?
Verfasst: Samstag 8. August 2009, 19:35
von Defnull
Was du suchst ist ein ORM (Object Relational Mapper) also den Kleber zwischen Objekten und Tabellarischen (rationalen) Datenbanken. Google mal nach SQLAlchemy.
Verfasst: Samstag 8. August 2009, 19:50
von ippurk
mhm, hat mir cofi auch schon vorgeschlagen, bleibt das Problem des SQL-Servers. Kann ich den prinzipiell so in eine Installationsroutine verpacken, daß der Endnutzer, wenn er denn dann mein tolles Programm installiert, damit nix zu tun hat ?
Verfasst: Samstag 8. August 2009, 19:58
von BlackJack
Die `sqlite3`-Bibliothek sollte bei Windows zum Lieferumfang von Python gehören und bei Linux ist's halt eine Abhängigkeit, die über die Paketverwaltung automatisch nachgezogen wird.
Verfasst: Samstag 8. August 2009, 20:00
von ippurk
heißt das, ich kann mit sqlite auf SQLalchemy zugreifen oder wie ?
Verfasst: Samstag 8. August 2009, 20:10
von cofi
Nein, andersrum. SQLAlchemy ist eine Abstraktionsschicht ueber der Datenbank, damit du dich nicht damit rumschlagen musst.
Verfasst: Samstag 8. August 2009, 20:19
von ippurk
heißt, ich müsste mir nur die SQLalchemy "Abstraktionsschicht" installieren und kann dann damit eine sqlite3 Datenbank bedienen ??
Verfasst: Samstag 8. August 2009, 20:24
von cofi
SQLAlchemy ist pure Python, d.h. du musst das sogar nur in den Ordner deines Programms legen. Die Datenbank kannst du auch so bedienen, allerdings nicht um damit ganze Objekte zu speichern, du muesstest die vorher serialisieren.
Den ganzen Kram erledigt SQLAlchemy.
Bevor du aber eine Datenbank damit fuettern kannst, solltest du dich erstmal in SQLAlchemy einlesen

Verfasst: Samstag 8. August 2009, 20:27
von ippurk
werd ich gerne, brauchte nur mal so eine Aussage zum grundlegenden Verständnis, aber das scheint ja schon genau das zu sein, was ich gesucht habe. Dann werd ich mal lesen, danke und bis später,
Verfasst: Sonntag 9. August 2009, 00:03
von Defnull
cofi hat geschrieben:... du muesstest die vorher serialisieren. Den ganzen Kram erledigt SQLAlchemy.
Mit dem Unterschied, das SQLAlchemy nicht einfach alles durch pickle jagt, sondern Datenbanken so verwendet, wie sie gedacht sind.
Grob zusammengefasst funktioniert das so:
Jedes von SQLAlchemy gemappte Objekt ist einer Tabelle in der Datenbank zugeordnet. Jedes Attribut des Objektes ist eine Spalte in der passenden Tabelle. Wenn du ein Objekt lädst, baut es SA aus den Daten in der Datenbank für dich zusammen. Wenn du es veränderst und dann speicherst, werden die Daten wieder in die Datenbank geschrieben. Da jedes Attribut der Objekte in einer eigenen Spalte steht, kann man darin suchen. Du kannst dir von SA also z.B. alle Blumen geben lassen, die rot sind, ohne jede einzelne Blume laden zu müssen.
Wenn du Assoziationen richtig definierst, kannst du auch z.B. eine Wohnung laden und von da aus direkt auf die Mieter der Wohnung zu greifen. SA weist dann nämlich, welche Mieter zu welcher Wohnung gehören.
Allerdings sollte man SQL oder wenigstens das Prinzip von relationalen Datenbanken verstanden und verinnerlicht haben, bevor man sich an SQLAlchemy wagt.
Einfach ist dieses ORM System nämlich nicht. Dafür ist es allerdings
mächtig
Verfasst: Sonntag 9. August 2009, 10:18
von sma
Ich würde so weit gehen und sagen, SQLalchemy ist viel zu kompliziert. Einfacher ist da z.B.
http://www.sqlobject.org/ oder
http://autumn-orm.org/.
Komplett von einer DB zu abstrahieren ist IMHO auch nicht der richtige Weg. Eigentlich ist Microsoft LINQ-Ansatz richtig. Von Nathan Sobo habe ich neulich eine Talk über eine JavaScript-Bibliothek gesehen, die einem Joins und Projections auf JavaScript-Objekten erlaubte, also den Kern einer RDB nicht versucht hat zu verstecken sondern im Gegenteil anzubieten. So etwas könnte man natürlich genauso gut auch in Python benutzen.
Stefan
Verfasst: Sonntag 9. August 2009, 16:12
von Hyperion
Wieso eigentlich wird
Elixir so selten empfohlen? Imho für den Einstieg ideal.
Verfasst: Sonntag 9. August 2009, 21:05
von ippurk
jut, dann hab ich mich also zumindest schon mal bruchstückhaft in diesen Chemiebaukasten eingelesen. Das Tutorial entspricht gott sei Dank auch zeimlich genau meinem ersten Konstrukt, nämlich Haus und seine Wohnungen. Funktioniert auch so, wie es soll. Die Herangehensweise gefällt mir so eigentlich ganz gut.
(hier mal schaun, da ist er, der Code)
Soweit hab ich die Arbeitsweise auch grob verstanden.
Erstes Problem: Laut Tutorial kann man ja die deklarative Methode benutzen, um die entsprechende Tabelle für das jeweilige Objekt anzulegen. Das versteh ich da so, daß ich mir diese anfängliche Schreiberei von Zeile 10 bis 24 eigentlich sparen kann, kommt ja alles nochmal in der Klasse. Geht bei mir nur irgendwie nicht, wenn das da nicht steht, legt der Kollege keine Tabellen an.
Zweite und wichtigere Frage: hat sich grad erst mal zurückgestellt.
und @Hyperion: Elixir ist also eine Abstraktionsschicht, die SQLAlchemy abstrahiert, also doppelt abstrakt oder wie ?
edit: Ja, genau, da materialisierte sich die zweite Frage auch schon wieder:
Die Wohnungen sollen eigentlich als Attribut eine Liste aller Mieter (oder deren id, wäre egal), die dort jemals gewohnt haben, haben, kombiniert mit Einzugs- und Auszugsdatum. Jetzt kann ich aber keine Liste mehr als Attirbut benutzen, oder ?
Verfasst: Montag 10. August 2009, 09:41
von sma
Elixir sollte sich eigentlich mit <
http://www.sqlalchemy.org/docs/05/refer ... ative.html> erledigt haben. Da ich aber Djangos ORM einfacher finde, hier mal das Beispiel:
Code: Alles auswählen
class Home(models.Model):
street = models.CharField()
city = models.CharField()
class Flat(models.Model):
square_meters = models.IntegerField()
home = models.ForeignKey(Home, related_name="flats")
class Tenant(models.Model):
name = models.CharField()
current_flat = models.ForeignKey(Flat, related_name="tenants")
Stefan
Verfasst: Montag 10. August 2009, 09:53
von ippurk
das liest sich schon ein wenig einfacher, als das, was ich hier grad am produzieren bin. Jetzt bringt mich doch nicht völlig durcheinander.
Kann ich denn mit diesem Django ORM auch das realisieren:
Eine Liste mit Listen aller Mieter, die schonmal in der Wohnung gewohnt haben in der Form (Mieterobjekt, Einzugsdatum, Auszugsdatum), die dann als Attribut der Wohnung geführt wird ?
Verfasst: Montag 10. August 2009, 10:07
von sma
Würde ich mit einem "Mietverhältnis" modellieren:
Code: Alles auswählen
class Tenancy(models.Model):
moved_in = models.DateField()
moved_out = models.DateField()
tenant = models.ForeignKey(Tenant, related_name="tenancies")
flat = models.ForeignKey(Flat, related_name="tenancies")
Liste aller Mieter einer Wohnung:
Code: Alles auswählen
class Flat...
def all_tenants(self):
return [(t.tenant.name, t.moved_in, t.moved_out)
for t in self.tenancies.order_by('moved_in')]
Es müsste noch einen effizienteren Weg geben, an den Namen des Mieters zu kommen, irgendwas mit `select_related`, doch ich bin zu faul zum Nachgucken.
Stefan
Verfasst: Montag 10. August 2009, 10:17
von ippurk
ah ok, ich war da so in ähnlicher Richtung unterwegs:
Code: Alles auswählen
class FlatsTenantHistory(Base):
__tablename__ = 'flats_tenant_history'
id = Column(Integer, primary_key=True)
tenant_id = Column(Integer, nullable=False)
date_of_move_in = Column(String)
flat_id = Column(Integer, ForeignKey('flats.id'))
tenant = relation(Flat, backref=backref('flats_tenant_history',
order_by=id))
def __init__(self, tenant_id, date_of_move_in):
self.tenant_id = tenant_id
self.date_of_move_in = date_of_move_in
, wobei deine Bezeichnung "Mietverhältnis" mir grad mal klargemacht hat, was ich da eigentlich selber mit meine. Nur bei mir wird nur die MieterID gespeichert. Versteh ich das richtig, daß
Code: Alles auswählen
tenant = models.ForeignKey(Tenant, related_name="tenancies")
also so eine Art Zeiger auf diesen speziellen Mieter ist ? Wär ja eigentlich dann so, wie es meinem Verständnis nach sein sollte.
Verfasst: Montag 10. August 2009, 13:37
von str1442
tenant referenziert für ein spezielles Exemplar dieser Klasse zu einem anderen Objekt derjenigen Klasse, die du im ForeignKey angibst, hier als Tenant. tenancies ist dann der Name einer Art Menge, die alle FlatsTenantHistory Objekte welche wie grade beschrieben in Beziehung zu Tenant stehen beinhaltet.
Verfasst: Dienstag 11. August 2009, 08:38
von sma
Der "related_name" bei Django ist die Rückrichtung der 1:N Assoziation, d.h. zu einem Mietverhältnis gehört eine Wohnung, wie man über "flat" erreicht und von der Wohnung aus kommt man mit "tenancies" zu alle Mietverhältnissen für diese Wohnung.
Stefan
Verfasst: Montag 17. August 2009, 20:58
von ippurk
So, da hab ich jetzt zumindest grundlegend dieses SA verstanden und wollte hier mal fragen, ob mein Code denn in der Form ausbaufähig ist, oder eher einer Komplettüberarbeitung bedarf:
http://paste.pocoo.org/show/134848/
(es geht immer noch um die Miethausverwaltung)
Schönen Gruß, Stephan