ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler...

30
ZODB Einführung Dresden, 13.01.2011 Dipl. inf. Ingo Keller Medienzentrum – Abteilung MIT

Transcript of ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler...

Page 1: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

ZODB Einführung

Dresden, 13.01.2011 Dipl. inf. Ingo Keller

Medienzentrum – Abteilung MIT

Page 2: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Übersicht

Motivation

Python Persistenz

ZODB

Beispiel

13.01.2011 ZODB Einführung Folie 1 von XYZ

Page 3: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

MOTIVATION Warum Objektorientierte Datenbanken?

13.01.2011 ZODB Einführung Folie 2 von XYZ

Page 4: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Einordnung

Ø  Datenbanktypen -  Relational -  Hierarchisch -  Objekt-Orientiert

Ø  Multi-Tier Architekturen

13.01.2011 ZODB Einführung Folie 3 von XYZ

Page 5: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Probleme Relationaler Datenbanken

ID Name Vorname Telefon EMail ...

1 Mustermann Max +41(0)555555 [email protected] ...

2 Vorwerk Frieda [email protected] ...

3 Schildkröte Paul 0351/232342 ...

... ... ... ... ... ...

13.01.2011 ZODB Einführung Folie 4 von XYZ

einfach erweiterbar

schwierig erweiterbar

Page 6: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Probleme Relationaler Datenbanken

Ø  Keine Speicherung mehrer Werte in einem Feld -  Ausnahme spezielle Datentypen > Datenbankabhängig

Ø  Keine Erweiterbarkeit von individuellen Datensätzen -  Lösung über weitere Tabellen via Fremdschlüssel > Aufwendigeres Verknüpfen über JOINs

Ø  Sehr aufwändig für komplexe Daten

Ø  Kein implizites Konzept von Objektorientierung und Vererbung -  Lösung über Object-Relational Mapper (z.B. SQLAlchemy) > Extra Entwicklungs- und Laufzeitaufwand

13.01.2011 ZODB Einführung Folie 5 von XYZ

Page 7: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

PYTHON PERSISTENZ Speichern, aber wie?

13.01.2011 ZODB Einführung Folie 6 von XYZ

Page 8: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Pickling

Ø  Modul cPickel -  Integraler Bestandteil von Python

Ø  Betriebssystem unabhängig

Ø  Serialisierung von Objekten in "ASCII"-Strings -  kostet Speicherplatz -  bringt Kodierungsunabhängigkeit

13.01.2011 ZODB Einführung Folie 7 von XYZ

Page 9: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Pickling Beispiel

13.01.2011 ZODB Einführung Folie 8 von XYZ

import cPickle d = [1,2,3,4] # Schreiben eines Dumps file = open('test.pic', 'w') cPickle.dump(d, file) file.close() # Lesen eines Dumps file = open('test.pic', 'r') a = cPickle.load(file) file.close() # Daten sind wieder da print a [1,2,3,4]

Page 10: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

test.pic

Ø  cat test.pic

(lp1 I1 aI2 aI3 aI4 a.

13.01.2011 ZODB Einführung Folie 9 von XYZ

Page 11: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

ZODB Und wieso jetzt Datenbank?

13.01.2011 ZODB Einführung Folie 10 von XYZ

Page 12: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Installation

Ø  Eigenständiges Python Produkt

Ø  Voraussetzung: -  Python + setuptools

Ø  Installation: easy_install ZODB3

Ø  Nutzung: >>> import ZODB

13.01.2011 ZODB Einführung Folie 11 von XYZ

Page 13: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Zope Object Database

Ø  Transaktionsorientierte Datenbank -  "two-phase commit" verfügbar

Ø  ACID-fähig -  Atomicity -  Consistency -  Isolation -  Durability

Ø  Undo / History / Timeshift

Ø  Skalierbar (Transaktionsrate, Objektmenge)

Ø  Unterstützt Binary Large Objects (BLOBs) 13.01.2011 ZODB Einführung Folie 12 von XYZ

Page 14: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Zope Object Database

Ø  Ist nicht SQL-fähig -  NoSQL-Datenbank

Ø  Keine Unterstützung von Replikation

Ø  Langsamer bei tabellenstrukturierten Daten

Ø  Ist nicht Zope -  wird aber von Zope genutzt

13.01.2011 ZODB Einführung Folie 13 von XYZ

Page 15: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

ZODB Kernideen

Ø  Architektur -  Storage, Datenbank, Wurzelobjekt ("root")

Ø  Transaktionen um Updates zu kontrollieren -  Sicheres Sharen zwischen Clients

Ø  Persistenz über Erreichbarkeit (Hierarchische DB) -  Alle erreichbaren Objekte werden gespeichert

13.01.2011 ZODB Einführung Folie 14 von XYZ

ZODB Root

Person Firma

PID Firstname Surname

Page 16: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Storagetypen

Ø  FileStorage -  einfach eine große Datei -  Achtung: maximale Dateigröße des Dateisystems bedenken!

Ø  MappingStorage -  Speichert Daten in einer In-Memory Datenbank

Ø  DemoStorage -  Wrapper um einen beliebigen Storage -  Transaktionen werden in einen separaten Storage geschrieben -  gewrappter Storage bleibt erhalten

Ø  und noch viele mehr

13.01.2011 ZODB Einführung Folie 15 von XYZ

Page 17: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Basisfunktionalität

# Notwendige Imports from ZODB import FileStorage, DB from persistent import Persistent import transaction # Verbindung zu einer Datenbank storage = FileStorage.FileStorage('/tmp/Data.fs') db = DB(storage) conn = db.open() # Root der Datenbank anfragen dbroot = conn.root() # Festschreiben oder abrechen einer Transaktion transaction.commit() transaction.abort()

13.01.2011 ZODB Einführung Folie 16 von XYZ

Page 18: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Persistenzklasse

Ø  ZODB kann alle pickelbaren Objekt speichern -  nicht pickelbar: z.B. Sockets, Device Files

Ø  Klasse Persistent als Baseclass für alle speicherbaren Klassen -  Kann als Mixin genutzt werden -  bietet alle Persistenzhooks -  transparente Persistenz

Ø  _p_ - Attribute managen den Persistenzzustand _p_changed – Verändert nach letztem Commit ? _p_mtime – Modifikationszeit _p_oid – OID des Objekts _p_estimated_size – Erwartete Recordgröße

13.01.2011 ZODB Einführung Folie 17 von XYZ

Page 19: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Transaktionen

Ø  transaction.begin() -  implizit über die Connections gegeben

Ø  transaction.commit() -  nur persistente Objekte automatisch betroffen!

Ø  transaction.abort() -  Transaktionsabbruch gilt nur für Datenbankobjekte

Ø  transaction.savepoint() -  neuere Savepoints werden ungültig beim zurückrollen zu älteren

Ø  transaction.doom()

13.01.2011 ZODB Einführung Folie 18 von XYZ

Page 20: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Minimal Beispiel

from persistent import Persistent from ZODB import FileStorage, DB import transaction class Counter(Persistent):

_value = 0 def inc(self): self._value += 1

def main():

fs = DB(FileStorage.FileStorage(“Data.fs”)) conn = db.open() root = conn.root() obj = root[“myCounter”] = Counter() transaction.commit() obj.inc() transaction.commit()

main()

13.01.2011 ZODB Einführung Folie 19 von XYZ

Page 21: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

OIDs & Records

Ø  OIDs sind 8 Byte Binärstrings die eine 64bit Zahl kodieren -  es gilt immer: conn.root()._p_oid == 0

Ø  Record entspricht einem Einzelobjektpickle -  Zugreifbar per OID > db._storage.load(oid)

Ø  Persistenzmechanismus verknüpft Objekte automatisch -  native Datentypen werden im Objekt gespeichert > verwenden von PersistentList, PersistentDict empfohlen

Ø  Datenbankänderung über Hinzufügen neuer Records -  OIDs wachsen monoton

13.01.2011 ZODB Einführung Folie 20 von XYZ

Page 22: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

TIDs & Undo

Ø  TIDs – Transaktionsidentifier -  sind im wesentlichen Zeitstempel & wachsen monoton

Ø  OIDs repräsentieren den Objektgraphen -  TIDs repräsentieren die zeitlichen Operationen auf dem Graph

Ø  Undo -  Zurücksetzen von TIDs

>>> db = ZODB.DB('Data.fs') >>> tid = db.lastTransaction() >>> db.undo(tid)

13.01.2011 ZODB Einführung Folie 21 von XYZ

Page 23: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

History / Time Travel

Ø  History -  TID-Graph eines Objekts

Ø  Time Travel -  Temporäres zurücksetzen des Zeigers auf den aktuellsten TID

13.01.2011 ZODB Einführung Folie 22 von XYZ

Page 24: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Packen & Backup

Ø  Storages wachsen immer nur -  Löschen entspricht Anfügen aktualisierter Daten mit neuem TID

Ø  Packen entfernt alle "veralteten" Transaktionen

> regelmässiges Packen notwendig

Ø  Hot Snapshots möglich -  simples kopieren der Data.fs > bei gleichzeitigem Schreiben besteht Gefahr von Datenkorruption > aber nur die letzten Transaktionen! Konsistenz bleibt gewahrt

Ø  Backuptool: repozo

13.01.2011 ZODB Einführung Folie 23 von XYZ

Page 25: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

ZODB Tools

Ø  Analyseskript:

>>> from ZODB.scripts.analyze import analyze, report >>> ... >>> print report(analyze(storage))

Processed 4084 records in 11 transactions Average record size is 267.07 bytes Average transaction size is 99154.27 bytes Types used: Class Name Count TBytes Pct AvgSize ------------------------------------ ------- --------- ----- ------- AccessControl.User.User 1 141 0.0% 141.00 AccessControl.User.UserFolder 1 103 0.0% 103.00 App.ApplicationManager.ApplicationManager 1 107 0.0% 107.00

13.01.2011 ZODB Einführung Folie 24 von XYZ

Page 26: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

ZODB Tools

Ø  checkbtrees -  rekursives checken aller BTrees

Ø  fsoids -  OID Tracer, liefer alle Informationen zu gegebenen OIDs

Ø  fsrefs -  checken von "Hängenden" Referenzen

Ø  fstail -  Dumped die letzten Transaktionen (wie tail)

Ø  fstest -  Konsistenzchecker

13.01.2011 ZODB Einführung Folie 25 von XYZ

Page 27: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

BEISPIEL Was kann man nun damit machen?

13.01.2011 ZODB Einführung Folie 26 von XYZ

Page 28: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Quellen

Ø  "Das Python Praxisbuch", F. Hajji, Addison-Wesley, 2008

Ø  "GoTo Python", D. Harms, Addison-Wesley, 2003

Ø  "Persistente Python-Objekte mit der ZODB", Chr. Theune, Workshop DZUG, 2009

Ø  http://www.zodb.org

13.01.2011 ZODB Einführung Folie 27 von XYZ

Page 29: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Storage Klasse

from persistent import Persistent class Person (Persistent):

def __init__(self, pid, firstname, surname): self.pid = pid self.firstname = firstname self.surname = surname def __str__(self): return 'Person(%s, %s, %s) % (self.pid, self.firstname, self.surname)

13.01.2011 ZODB Einführung Folie 28 von XYZ

Page 30: ZODB Einführung - TU Dresdenknoll/python/material/Sommerku...Pickling ! Modul cPickel - Integraler Bestandteil von Python ! Betriebssystem unabhängig ! Serialisierung von Objekten

Abgeleitete Storage Klasse

13.01.2011 ZODB Einführung Folie 29 von XYZ

class PersonNG (Persistent): def __init__(self, pid, firstname, surname, email, website): Person.__init__(pid, firstname, surname) self.email = email self.website = website def __str__(self): return 'PersonNG(%s, %s, %s, %s, %s) % ( self.pid, self.firstname, self.surname, self.email, self.url)