La base de datos de objetos Zope ( ZODB ) es una base de datos orientada a objetos para almacenar objetos Python de forma transparente y persistente . Se incluye como parte del servidor de aplicaciones web de Zope , pero también se puede utilizar de forma independiente de Zope.
Desarrollador (es) | Fundación Zope |
---|---|
Lanzamiento estable | 5.6.0 [1] / 11 de junio de 2020 |
Repositorio | github |
Escrito en | Pitón |
Sistema operativo | Multiplataforma |
Tipo | Base de datos de objetos |
Licencia | Licencia pública de Zope |
Sitio web | www |
Las características de ZODB incluyen: transacciones, historial / deshacer, almacenamiento conectable de forma transparente, almacenamiento en caché integrado, control de concurrencia de múltiples versiones (MVCC) y escalabilidad a través de una red (usando ZEO ).
Historia
- Creado por Jim Fulton de Zope Corporation a finales de los 90.
- Comenzó como un simple sistema de objetos persistentes (POS) durante el desarrollo de Principia (que luego se convirtió en Zope)
- Se cambió el nombre de ZODB 3 cuando se realizó un cambio significativo en la arquitectura.
- ZODB 4 fue un proyecto de corta duración para volver a implementar todo el paquete ZODB 3 utilizando 100% Python.
Implementación
Lo esencial
ZODB almacena objetos de Python utilizando una versión extendida de la persistencia de objetos incorporada de Python (pickle). Una base de datos ZODB tiene un único objeto raíz (normalmente un diccionario), que es el único objeto directamente accesible por la base de datos. Todos los demás objetos almacenados en la base de datos se alcanzan 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 simultáneas mediante MVCC y realiza un seguimiento de los cambios en los objetos por objeto. Solo se confirman los objetos modificados. Las transacciones no son destructivas por defecto y se pueden revertir.
Ejemplo
Por ejemplo, digamos que tenemos un coche se describe el uso de 3 clases Car
, Wheel
y Screw
. En Python, esto podría representarse de la siguiente manera:
clase Coche : [ ... ] clase Rueda : [ ... ] clase Tornillo : [ ... ]myCar = Coche () myCar . wheel1 = Wheel () myCar . wheel2 = Wheel () para wheel in ( myCar . wheel1 , myCar . wheel2 ): rueda . tornillos = [ Tornillo (), Tornillo ()]
Si la variable mycar es la raíz de la persistencia, entonces:
zodb [ 'mycar' ] = myCar
Esto almacena todas las instancias de objetos (automóvil, rueda, tornillos, etc.), que se pueden recuperar más tarde. Si otro programa obtiene una conexión a la base de datos a través del objeto mycar, realizando:
car = zodb [ 'myCar' ]
Y recupera todos los objetos, el puntero al automóvil se mantiene en la car
variable. Luego, en una etapa posterior, este objeto se puede modificar con un código Python como:
coche . wheel3 = Wheel () coche . rueda 3 . tornillos = [ Tornillo ()]
El almacenamiento se modifica para reflejar el cambio de datos (después de que se ordena una confirmación).
No hay una declaración de la estructura de datos ni en Python ni en ZODB, por lo que se pueden agregar campos nuevos libremente a cualquier objeto existente.
Unidad de almacenamiento
Para que tenga lugar la persistencia, la clase Python Car debe derivarse de la persistencia. Clase persistente: esta clase contiene los datos necesarios para que funcione la maquinaria de persistencia, como la identificación del objeto interno, 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 Persistente es la unidad atómica de almacenamiento (el objeto completo se copia en el almacenamiento cuando se modifica un campo).
En el ejemplo anterior, si Car
es la única clase derivada de Persistent, cuando wheel3
se agrega a car, todos los objetos deben escribirse en el almacenamiento. Por el contrario, si Wheel
también se deriva de Persistent, cuando carzz.wheel3 = Wheel
se realiza, se escribe un nuevo registro en el almacenamiento para contener el nuevo valor del Car
, pero Wheel
se mantienen los existentes , y el nuevo registro para los Car
puntos al Wheel
registro ya existente dentro del almacenamiento.
La maquinaria ZODB no persigue la modificación a través del gráfico de punteros. En el ejemplo anterior, carzz.wheel3 = something
es una modificación rastreada automáticamente por la maquinaria ZODB, porque carzz
es de la clase (Persistente) Car
. La maquinaria ZODB hace esto marcando el registro como sucio . Sin embargo, si hay una lista, cualquier cambio dentro de la lista no es notado por la maquinaria 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 estar al tanto del funcionamiento de la maquinaria de persistencia.
Atomicidad
La unidad de almacenamiento (es decir, un objeto cuya clase deriva de Persistent) es también la unidad de atomicidad . En el ejemplo anterior, si Cars
es la única clase persistente, un hilo modifica una rueda (el Car
registro debe ser notificado) y otro hilo modifica otro Wheel
dentro de otra transacción, la segunda confirmación fallará. Si Wheel
también es persistente, ambos Wheels
se pueden modificar de forma independiente mediante dos hilos diferentes en dos transacciones diferentes.
Persistencia de clase
La persistencia de la clase (escribir la clase de un objeto en particular en el almacenamiento) se obtiene escribiendo una especie de nombre "completamente calificado" de la clase en cada registro del disco. En Python, el nombre de la clase implica la jerarquía del directorio en el que reside el archivo fuente de la clase. Una consecuencia es que el archivo fuente del objeto persistente no se puede mover. Si es así, la maquinaria ZODB no puede localizar la clase de un objeto cuando lo recupera del almacenamiento, lo que resulta en un objeto roto.
ZEO
Zope Enterprise Objects (ZEO) es una implementación de almacenamiento ZODB que permite que múltiples procesos de cliente persistan objetos en un solo servidor ZEO. Esto permite una escala transparente.
Almacenamientos enchufables
- Almacenamiento en red (también conocido como ZEO): permite que múltiples procesos de Python carguen y almacenen instancias persistentes al mismo tiempo.
- Almacenamiento de archivos: permite que un solo proceso de Python se comunique con un archivo en el disco.
- relstorage: permite que el almacenamiento de respaldo de persistencia sea un RDBMS .
- Almacenamiento de directorios: cada dato persistente se almacena como un archivo separado en el sistema de archivos. Similar a FSFS en Subversion .
- Almacenamiento de demostración: un back-end en memoria para el almacenamiento persistente.
- BDBStorage: que utiliza el back-end de Berkeley DB . Ahora abandonado.
Tecnologías de conmutación por error
- Servicios de replicación de Zope (ZRS): un complemento comercial (de código abierto desde mayo de 2013) que elimina el punto único de falla, brindando respaldo en caliente para escrituras y balanceo de carga para lecturas.
- zeoraid: una solución de código abierto que proporciona un servidor de red proxy que distribuye los almacenes de objetos y la recuperación a través de una serie de servidores de red.
- almacenamiento: dado que se utilizan tecnologías RDBMS, esto evita la necesidad de un servidor ZEO.
- NEO: implementación de almacenamiento distribuido (tolerancia a fallas, equilibrio de carga).