Creo que traté de pedir demasiado en my previous question así que me disculpo por eso. Permítanme exponer mi situación de la manera más simple posible esta vez.Ayuda con copia y copia profunda en Python
Básicamente, tengo un montón de diccionarios que hacen referencia a mis objetos, que a su vez se asignan utilizando SQLAlchemy. Todo bien conmigo Sin embargo, quiero hacer cambios iterativos en los contenidos de esos diccionarios. El problema es que al hacerlo cambiarán los objetos a los que hacen referencia --- y usar copy.copy() no sirve de nada ya que solo copia las referencias contenidas dentro del diccionario. Por lo tanto, aunque copie algo, cuando lo intente, diga print
el contenido del diccionario, solo obtendré los últimos valores actualizados para el objeto.
Es por eso que quería utilizar copy.deepcopy() pero eso no funciona con SQLAlchemy. Ahora estoy en un dilema ya que necesito copiar ciertos atributos de mi objeto antes de hacer dichos cambios iterativos.
En resumen, necesito usar SQLAlchemy y al mismo tiempo, me aseguro de que puedo tener una copia de los atributos de mis objetos cuando realizo cambios para que no cambie el objeto al que se hace referencia.
¿Algún consejo, ayuda, sugerencias, etc.?
Edit:
Han añadido algunos códigos.
class Student(object):
def __init__(self, sid, name, allocated_proj_ref, allocated_rank):
self.sid = sid
self.name = name
self.allocated_proj_ref = None
self.allocated_rank = None
students_table = Table('studs', metadata,
Column('sid', Integer, primary_key=True),
Column('name', String),
Column('allocated_proj_ref', Integer, ForeignKey('projs.proj_id')),
Column('allocated_rank', Integer)
)
mapper(Student, students_table, properties={'proj' : relation(Project)})
students = {}
students[sid] = Student(sid, name, allocated_project, allocated_rank)
Por lo tanto, los atributos que se van a cambiar son los allocated_proj_ref
y allocated_rank
atributos. El students_table
está codificado con la identificación de estudiante única (sid
).
Question
me gustaría que persistan los atributos que cambiar de arriba - es decir, eso es, básicamente, por la que decidí utilizar SQLA. Sin embargo, el objeto mapeado cambiará, lo cual no es recomendable. Por lo tanto, si realizo los cambios en doppelgänger, objeto no mapeado ... puedo tomar esos cambios y actualizar los campos/tabla para el objeto mapeado.
En cierto sentido sigo el secondary solution de David donde creo otra versión de la clase que no está mapeada.
He intentado utilizar la solución StudentDBRecord
se menciona más adelante, pero tiene un error!
File "Main.py", line 25, in <module>
prefsTableFile = 'Database/prefs-table.txt')
File "/XXXX/DataReader.py", line 158, in readData
readProjectsFile(projectsFile)
File "/XXXX/DataReader.py", line 66, in readProjectsFile
supervisors[ee_id] = Supervisor(ee_id, name, original_quota, loading_limit)
File "<string>", line 4, in __init__
raise exc.UnmappedClassError(class_)
sqlalchemy.orm.exc.UnmappedClassError: Class 'ProjectParties.Student' is not mapped
¿Quiere decir esto que Student
debe ser mapeadas?
Health warning!
Alguien señaló un muy buen tema adicional aquí. Mira, incluso si llamo al copy.deepcopy()
en un objeto no mapeado, en este caso, asumamos que es el diccionario de estudiantes que he definido anteriormente, deepcopy hace una copia de todo.Mi allocated_proj_ref
es en realidad un objeto Project
, y tengo un diccionario correspondiente projects
para eso.
Así que DeepCopy tanto students
y projects
- la cual soy - dice que voy a tener casos en los que el atributo allocated_proj_ref
students
's va a tener problemas con el juego con casos en el diccionario projects
.
Por lo tanto, supongo que tendré que redefinir/anular (así se llama, ¿no?) deepcopy
en cada clase utilizando def __deecopy__(self, memo):
o algo así?
Me Me gustaría anular __deepcopy__
tal que no tiene en cuenta todas las cosas SQLA (que son <class 'sqlalchemy.util.symbol'>
y <class 'sqlalchemy.orm.state.InstanceState'>
), pero copia todo lo demás que es parte de la clase asignada.
¿Alguna sugerencia, por favor?
Al modificar los objetos mapeados, ¿desea que los originales o las versiones modificadas a persistir? –
@ Winston: O bien persisten los originales o bien persiste una versión modificada específica ('best' - ver ediciones). Ya puedo ver problemas con este último ya que 'best' no se queda quieto ya que estoy actualizando el objeto en sí. Suspiro. – PizzAzzra
En respuesta a sus ediciones: ¿por qué diablos está usando una base de datos para hacer esto? Tendría más sentido tener 'Estudiante' como una clase de Python normal, y almacenarlo en una base de datos (o archivo) solo después de que encuentre el óptimo global. –