Hi there,
I think I tried to ask for far too much in my previous question so apologies for that. Let me lay out my situation in as simple a manner as I can this time.
Basically, I've got a bunch of dictionaries that reference my objects, which are in turn mapped using SQLAlchemy. All fine with me. However, I want to make iterative changes to the contents of those dictionaries. The problem is that doing so will change the objects they reference---and using copy.copy() does no good since it only copies the references contained within the dictionary. Thus even if copied something, when I try to, say print
the contents of the dictionary, I'll only get the latest updated values for the object.
This is why I wanted to use copy.deepcopy() but that does not work with SQLAlchemy. Now I'm in a dilemma since I need to copy certain attributes of my object before making said iterative changes.
In summary, I need to use SQLAlchemy and at the same time make sure I can have a copy of my object attributes when making changes so I don't change the referenced object itself.
Any advice, help, suggestions, etc.?
Edit:
Have added some code.
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)
Thus, the attributes that I will be changing are the allocated_proj_ref
and allocated_rank
attributes. The students_table
is keyed using the unique student ID (sid
).
Question
I'd want to persist the attributes I change above -- I mean, that's basically why I decided to use SQLA. However, the mapped object will be changing, which is not recommended. Thus, if I make the changes to doppelgänger, unmapped object... can I take those changes and update the fields/table for the mapped object.
In a sense I'm following David's secondary solution where I create another version of the Class that isn't mapped.
I tried using the StudentDBRecord
solution mentioned below but got an 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
Does this mean that Student
must be mapped?
Health warning!
Someone pointed out a really good additional issue here. See, even if I'm calling copy.deepcopy()
on a non-mapped object, in this case, let's assume it's the students dictionary I've defined above, deepcopy makes a copy of everything. My allocated_proj_ref
is actually a Project
object, and I've got a corresponding projects
dictionary for that.
So I deepcopy both students
and projects
-- which I am -- he says I'll have cases where the students
's allocated_proj_ref
attribute will have issues with matching with instances in the projects
dictionary.
Thus, I take it that I'll have to redefine/override (that's what it's called isn't it?) deepcopy
in each Class using def __deecopy__(self, memo):
or something like that?
I'd I'd like to override __deepcopy__
such that it ignores all the SQLA stuff (which are <class 'sqlalchemy.util.symbol'>
and <class 'sqlalchemy.orm.state.InstanceState'>
) but copy everything else that's part of the a mapped class.
Any suggestions, please?