La base de datos de objetos Zope ( ZODB ) es una base de datos orientada a objetos que permite almacenar objetos Python de forma transparente y persistente . Está incluida en el servidor de aplicaciones web Zope , pero también puede utilizarse de forma independiente.
Las características de ZODB incluyen: transacciones, historial/deshacer, almacenamiento conectable de forma transparente, almacenamiento en caché integrado, control de concurrencia multiversión (MVCC) y escalabilidad a través de una red (mediante ZEO ).
Historia
La base de datos de objetos Zope (ZODB) fue creada por Jim Fulton de Zope Corporation a finales de la década de 1990. Inicialmente, comenzó como un sencillo sistema de objetos persistentes (POS) durante el desarrollo de Principia, que posteriormente evolucionó hasta convertirse en Zope. Un cambio arquitectónico significativo llevó a que el sistema pasara a llamarse ZODB 3. Posteriormente, se presentó ZODB 4 como un proyecto de corta duración cuyo objetivo era reimplementar todo el paquete ZODB 3 utilizando Python al 100%.
Implementación
Lo esencial
ZODB almacena objetos de Python mediante una versión extendida del mecanismo de persistencia de objetos integrado de Python (pickle). Una base de datos ZODB tiene un único objeto raíz (normalmente un diccionario), que es el único objeto directamente accesible desde la base de datos. Todos los demás objetos almacenados en la base de datos se acceden a través del objeto raíz. Los objetos a los que hace referencia un objeto almacenado en la base de datos también se almacenan automáticamente en la base de datos.
ZODB admite transacciones concurrentes mediante MVCC y realiza un seguimiento de los cambios en los objetos de forma individual. Solo se confirman los objetos modificados. Las transacciones no son destructivas por defecto y se pueden revertir.
Ejemplo
Por ejemplo, supongamos que tenemos un automóvil descrito usando 3 clases Car, Wheely Screw. En Python, esto podría representarse de la siguiente manera:
Clase Coche : [ ... ] Clase Rueda : [ ... ] Clase Tornillo : [ ... ]miCoche = Coche () miCoche . rueda1 = Rueda () miCoche . rueda2 = Rueda () para rueda en ( miCoche . rueda1 , miCoche . rueda2 ): rueda . tornillos = [ Tornillo (), Tornillo ()]Si la variable mycar es la raíz de la persistencia, entonces:
zodb [ 'mycar' ] = myCarEsto coloca todas las instancias de objetos (coche, rueda, tornillos, etc.) en almacenamiento, que se puede recuperar posteriormente. Si otro programa obtiene una conexión a la base de datos a través del objeto mycar, realizará lo siguiente:
coche = zodb [ 'myCar' ]Y recupera todos los objetos, manteniendo el puntero al coche en la carvariable. Posteriormente, este objeto puede modificarse con un código Python como este:
coche.rueda3 = Rueda ( ) coche.rueda3.tornillos = [ Tornillo ( ) ]El almacenamiento se modifica para reflejar el cambio de datos (después de que se ordena una confirmación).
Ni en Python ni en ZODB se declara la estructura de datos , por lo que se pueden añadir libremente nuevos campos a cualquier objeto existente.
Unidad de almacenamiento
Para que se produzca la persistencia, la clase Python Car debe derivarse de la Persistence.Persistentclase Persistent; esta clase contiene los datos necesarios para que funcione el mecanismo de persistencia, como el ID interno del objeto, el estado del objeto, etc., pero también define el límite de la persistencia en el siguiente sentido: cada objeto cuya clase deriva de Persistent es la unidad atómica de almacenamiento (el objeto completo se copia al almacenamiento cuando se modifica un campo).
En el ejemplo anterior, si Cares la única clase que deriva de Persistent, cuando wheel3se agrega a car, todos los objetos deben escribirse en el almacenamiento. Por el contrario, si Wheeltambién deriva de Persistent, entonces cuando carzz.wheel3 = Wheelse realiza, se escribe un nuevo registro en el almacenamiento para contener el nuevo valor de Car, pero los existentes Wheelse mantienen, y el nuevo registro para Carapunta al registro ya existente Wheeldentro del almacenamiento.
El mecanismo de ZODB no rastrea las modificaciones a través del grafo de punteros. En el ejemplo anterior, carzz.wheel3 = somethinges una modificación rastreada automáticamente por el mecanismo de ZODB, porque carzzes de la clase (persistente) Car. El mecanismo de ZODB hace esto marcando el registro como dirty. Sin embargo, si hay una lista, cualquier cambio dentro de la lista no es detectado por el mecanismo de ZODB, y el programador debe ayudar agregando manualmente carzz._p_changed = 1, notificando a ZODB que el registro realmente cambió. Por lo tanto, hasta cierto punto, el programador debe conocer el funcionamiento del mecanismo de persistencia.
Atomicidad
La unidad de almacenamiento (es decir, un objeto cuya clase deriva de Persistent) también es la unidad de atomicidad . En el ejemplo anterior, si Carses la única clase Persistent, un hilo modifica un Wheel (el Carregistro debe ser notificado) y otro hilo modifica otro Wheeldentro de otra transacción, la segunda confirmación fallará. Si Wheeltambién es Persistent, ambos Wheelspueden ser modificados independientemente por dos hilos diferentes en dos transacciones diferentes.
persistencia de clase
La persistencia de clases —que consiste en escribir la clase de un objeto específico en el almacenamiento— se logra escribiendo el nombre completo de la clase en cada registro del disco. En Python, el nombre de la clase depende de la jerarquía de directorios donde se encuentra el archivo fuente. Esto implica que el archivo fuente del objeto persistente no se puede mover. Si se mueve, el sistema ZODB no puede localizar la clase del objeto al recuperarlo del almacenamiento, lo que provoca que el objeto se corrompa.
CERO
Zope Enterprise Objects (ZEO) es una implementación de almacenamiento ZODB que permite que múltiples procesos cliente almacenen objetos en un único servidor ZEO. Esto facilita el escalado transparente.
Almacenamientos enchufables
El almacenamiento en red (también conocido como ZEO) permite que varios procesos de Python carguen y almacenen instancias persistentes simultáneamente. El almacenamiento de archivos permite que un único proceso de Python interactúe con un archivo en disco. RelStorage permite que el almacenamiento de respaldo de persistencia sea un RDBMS . El almacenamiento de directorios almacena cada dato persistente como un archivo separado en el sistema de archivos, similar a FSFS en Subversion . Demo Storage funciona como un backend en memoria para el almacenamiento persistente. BDBStorage, ahora abandonado, utilizaba un backend de Berkeley DB .
Tecnologías de conmutación por error
Zope Replication Services (ZRS) es un complemento comercial de conmutación por error , de código abierto desde mayo de 2013, que elimina el punto único de fallo , proporcionando copias de seguridad en caliente para escrituras y equilibrio de carga para lecturas. ZeoRAID es una solución de código abierto que ofrece un servidor de red proxy que distribuye el almacenamiento de objetos y la recuperación a través de una serie de servidores de red. RelStorage, mediante el uso de tecnologías RDBMS, elimina la necesidad de un servidor ZEO. NEO es una implementación de almacenamiento distribuido que proporciona tolerancia a fallos y equilibrio de carga.
Referencias
Enlaces externos
- Sitio web oficial de ZODB
- Libro ZODB
- Guía de programación de ZODB. Archivada el 25/01/2016 en Wayback Machine.
- Introducción a la base de datos de objetos Zope. Archivado el 27/01/2016 en Wayback Machine.
- Software multiplataforma
- Sistemas de gestión de bases de datos gratuitos
- Sistemas de gestión de bases de datos orientados a objetos
- Software ORDBMS para Linux
- Software programado en Python