Estoy buscando consejos sobre los métodos para implementar la persistencia de objetos en Python. Para ser más precisos, deseo poder vincular un objeto de Python a un archivo de tal manera que cualquier proceso de Python que abra una representación de ese archivo comparta la misma información, cualquier proceso puede cambiar su objeto y los cambios se propagarán a los otros procesos, e incluso si todos los procesos que "almacenan" el objeto están cerrados, el archivo permanecerá y puede ser reabierto por otro proceso.Persistencia de objeto Python
Encontré tres candidatos principales para esto en mi distribución de Python - anydbm, pickle, y shelve (dbm parecía ser perfecto, pero es de Unix solamente, y estoy en Windows). Sin embargo, todos ellos tienen defectos:
- anydbm sólo puede manejar un diccionario de valores de cadena (estoy tratando de almacenar una lista de diccionarios, todos los cuales tienen claves de las cadenas y los valores de cadena, aunque idealmente me gustaría buscar una módulo sin restricciones de tipo)
- shelve requiere que un archivo se vuelva a abrir antes de que se propaguen los cambios; por ejemplo, si dos procesos A y B cargan el mismo archivo (que contiene una lista vacía archivada) y A agrega un elemento al list y calls sync(), B seguirá viendo la lista como vacía hasta que vuelva a cargar el archivo.
- pickle (el módulo que estoy usando actualmente para mi implementación de prueba) tiene el mismo "requisito de recarga" que shelve, y tampoco sobrescribe datos previos, si el proceso A vacía 180 cadenas vacías en un archivo, y luego la cadena ' hola ', el proceso B tendrá que cargar el archivo dieciséis veces para obtener la cadena' hola '. Actualmente estoy lidiando con este problema precediendo cualquier operación de escritura con lecturas repetidas hasta el final del archivo ("borrando la pizarra antes de escribir sobre ella"), y haciendo que cada operación de lectura se repita hasta el final del archivo, pero siento que debe haber una mejor manera.
Mi módulo ideal sería comportarse como sigue (con el código "A >>>" código que representa ejecutado por el proceso A, y "B >>>" ejecutado por el procedimiento B):
A>>> import imaginary_perfect_module as mod
B>>> import imaginary_perfect_module as mod
A>>> d = mod.load('a_file')
B>>> d = mod.load('a_file')
A>>> d
{}
B>>> d
{}
A>>> d[1] = 'this string is one'
A>>> d['ones'] = 1 #anydbm would sulk here
A>>> d['ones'] = 11
A>>> d['a dict'] = {'this dictionary' : 'is arbitrary', 42 : 'the answer'}
B>>> d['ones'] #shelve would raise a KeyError here, unless A had called d.sync() and B had reloaded d
11 #pickle (with different syntax) would have returned 1 here, and then 11 on next call
(etc. for B)
I podría lograr este comportamiento creando mi propio módulo que usa pickle, y editando el volcado y el comportamiento de carga para que usen las lecturas repetidas que mencioné anteriormente, pero me cuesta creer que este problema nunca se haya producido y haya sido resuelto por , los programadores más talentosos antes. Además, estas lecturas repetidas me parecen ineficaces (aunque debo admitir que mi conocimiento de la complejidad de la operación es limitado, y es posible que estas repetidas lecturas se desarrollen "detrás de escena" en módulos aparentemente más suaves como shelve). Por lo tanto, concluyo que debo estar perdiendo algún módulo de código que me resolvería el problema. Estaría agradecido si alguien pudiera señalarme en la dirección correcta, o dar consejos sobre la implementación.
Dar una mirada a 'mongo-db'. No está tan completamente integrado en el lenguaje como su ejemplo anterior, pero le dará una base de datos mucho más robusta y tolerante que el escalado al sistema de archivos y ser inteligente con los bloqueos. – slezica