shelve — Almacenamiento persistente de objetos¶
Propósito: | El módulo shelve implementa el almacenamiento persistente para objetos arbitrarios de Python que pueden ser serializados, usando una interfaz de programación similar a un diccionario. |
---|
El módulo shelve
puede usarse como una opción simple de almacenamiento
persistente para objetos de Python cuando no se requiere una base de datos
relacional. Se accede al estante mediante llaves, igual que con un diccionario.
Los valores son serializados y se escriben en una base de datos creada. y
gestionada por dbm
.
Crear un nuevo estante¶
La forma más simple de usar shelve
es a través de la clase
DbfilenameShelf
. Utiliza dbm
para almacenar los datos. La clase
puede ser utilizada directamente, o llamando a shelve.open()
.
import shelve
with shelve.open('test_shelf.db') as s:
s['key1'] = {
'int': 10,
'float': 9.5,
'string': 'Sample data',
}
Para volver a acceder a los datos, abre el estante y utilízalo como un diccionario.
import shelve
with shelve.open('test_shelf.db') as s:
existing = s['key1']
print(existing)
La ejecución de ambas secuencias de comandos del ejemplo produce el siguiente resultado.
$ python3 shelve_create.py
$ python3 shelve_existing.py
{'string': 'Sample data', 'int': 10, 'float': 9.5}
El módulo dbm
no admite la escritura de múltiples aplicaciones a la
misma base de datos al mismo tiempo, pero soporta clientes de solo lectura
concurrentes. Si un cliente no va a modificar el estante, dígale a shelve
para que abra la base de datos de solo lectura al pasar flag='r'
.
import dbm
import shelve
with shelve.open('test_shelf.db', flag='r') as s:
print('Existing:', s['key1'])
try:
s['key1'] = 'new value'
except dbm.error as err:
print('ERROR: {}'.format(err))
Si el programa intenta modificar la base de datos mientras se abre solo para
lectura, se genera una excepción de error de acceso. El tipo de excepción
depende del módulo de base de datos seleccionado por dbm
cuando se creó
la base de datos.
$ python3 shelve_readonly.py
Existing: {'string': 'Sample data', 'int': 10, 'float': 9.5}
ERROR: cannot add item to database
Reescritura de datos¶
Los estantes no rastrean las modificaciones a los objetos volátiles, por defecto. Eso significa que si el contenido de un artículo almacenado en el estante es cambiado, el estante debe actualizarse explícitamente almacenando todo el artículo otra vez.
import shelve
with shelve.open('test_shelf.db') as s:
print(s['key1'])
s['key1']['new_value'] = 'this was not here before'
with shelve.open('test_shelf.db', writeback=True) as s:
print(s['key1'])
En este ejemplo, el diccionario en 'key1'
no se almacena nuevamente, por lo
que cuando el estante se vuelve a abrir, los cambios no se han conservado.
$ python3 shelve_create.py
$ python3 shelve_withoutwriteback.py
{'string': 'Sample data', 'int': 10, 'float': 9.5}
{'string': 'Sample data', 'int': 10, 'float': 9.5}
Para capturar automáticamente los cambios en los objetos volátiles almacenados en el estante, ábrelo con la escritura habilitada. La bandera writeback` causa que el estante recuerde todos los objetos recuperados de la base de datos usando un caché en memoria. Cada objeto de caché también se escribe de nuevo en la base de datos cuando el estante se cierra.
import shelve
import pprint
with shelve.open('test_shelf.db', writeback=True) as s:
print('Initial data:')
pprint.pprint(s['key1'])
s['key1']['new_value'] = 'this was not here before'
print('\nModified:')
pprint.pprint(s['key1'])
with shelve.open('test_shelf.db', writeback=True) as s:
print('\nPreserved:')
pprint.pprint(s['key1'])
Aunque reduce la posibilidad de error del programador, y puede hacer La persistencia de objetos más transparente, utilizar el modo de reescritura puede no ser deseable en todas las situaciones. El caché consume memoria extra mientras el estante está abierto y se detiene para escribir todos los objetos almacenados en caché La base de datos cuando se cierra ralentiza la aplicación. Toda la los objetos almacenados en caché se escriben de nuevo en la base de datos porque no hay manera de saber si han sido modificados. Si la aplicación lee más datos de los que escribe, la reescritura afectará el rendimiento innecesariamente.
$ python3 shelve_create.py
$ python3 shelve_writeback.py
Initial data:
{'float': 9.5, 'int': 10, 'string': 'Sample data'}
Modified:
{'float': 9.5,
'int': 10,
'new_value': 'this was not here before',
'string': 'Sample data'}
Preserved:
{'float': 9.5,
'int': 10,
'new_value': 'this was not here before',
'string': 'Sample data'}
Tipos específicos de estantes¶
Todos los ejemplos anteriores utilizaron la implementación predeterminada del
estante. Utilizar shelve.open()
en lugar de una de las implementaciones de
estantería directamente es un patrón de uso común, especialmente si no importa
qué tipo de base de datos se utiliza para almacenar los datos. Hay veces, sin
embargo, cuando el formato de la base de datos es importante. En esas
situaciones, usa DbfilenameShelf
o BsdDbShelf
directamente, o incluso
hereda de Shelf
para una solución personalizada.
Ver también
- Documentación de la biblioteca estándar para shelve
dbm
– El módulodbm
encuentra una biblioteca DBM disponible para crear una nueva base de datos.- feedcache – El módulo
feedcache
usashelve
como opción de almacenamiento por defecto. - shove – Shove implementa una interfaz de programación similar con más formatos de back-end.