On 06/03/2010 02:33 PM, Az wrote:
> Firstly, apologies if I'm demanding too much but basically I'm quite a
> beginner at Python programming and this is for a University project,
> which is why I'm keen to get this done (due in a few days!). So I hope
> you won't mind me asking some questions that may seem really basic.
>
>
>> deepcopy has issues because SQLAlchemy places extra information on your
>> objects, i.e. an _sa_instance_state attribute, that you dont want in your
>> copy. You *do* however need one to exist on your object. Therefore
>> deepcopy is not supported right now by SQLAlchemy ORM objects.
>>
>
>> There are ways to manually blow away the old _sa_instance_state and put a
>> new one on the object, but the most straightforward is to make a new
>> object with __init__() and set up the attributes that are significant,
>> instead of doing a full deep copy.
>>
> Could you explain what you mean by creating a new object with
> __init__() and setting up the attributes? Would this be a new class
> that isn't mapped using SQLA?
>
>
He just means creating a new instance of your mapped class and settings
its attributes manually, e.g.:
def copy(self):
copy = MyMappedClass()
copy.attr1 = self.attr1
copy.attr2 = self.attr2
return copy
>> if you do really want to use deepcopy, you'd have to implement
>> __deepcopy__() on your objects and ensure that a new _sa_instance_state is
>> set up,
>> there are functions in sqlalchemy.orm.attributes which can help with that.
>> This *should* be made an official SQLA recipe, but we haven't gotten
>> around to it.
>>
> Could you please explain what you mean by that? Would it be possible
> to give me an idea or an example of how such would work?
>
>
In theory you can use a generic __deepcopy__ implementation for ORM
classes. A very simple version might be:
def orm_deepcopy(self, memo):
mapper = class_mapper(self.__class__)
result = self.__class__()
memo[id(self)] = result
for prop in mapper.iterate_properties():
value = getattr(self, prop.key)
setattr(result, prop.key, deepcopy(value, memo))
return result
class MyMappedClass(...):
__deepcopy__ = orm_deepcopy
Beware that this implementation does not handle overlapping properties
well (e.g. relations and their corresponding foreign key columns),
lazy-loading properties, read-only properties, clearing out
auto-incrementing primary keys, etc. I would not recommend this
approach, as a use-case-specific copy() method will be much easier to
tailor to your needs.
>>> How can I stop it from closing the
>>> sessions?
>>>
>
>> nothing in SQLA closes sessions. Your program is doing that.
>>
> I'm not issuing a session.close() anywhere (I checked). Are there any
> other ways of closing a session besides that? (If the answer is
> "Plenty", don't worry about it... I'll try to track it down then)
>
If you are in a web framework, it may be closing the session for you
(usually by calling Session.remove() on a ScopedSession). Additionally,
are you sure that your object-to-copy is not transient when you make
your deepcopy?
-Conor
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.