SQLAlchemy mapped classes and __new__ (ClassManager.new_instance undocumented)

82 views
Skip to first unread message

Torsten Landschoff

unread,
Jun 28, 2011, 3:45:48 AM6/28/11
to sqlal...@googlegroups.com
Hi *,

a while ago I noticed a small problem with SQLAlchemy. I was able to
work around this, but I am still wondering if this should be required.

I am doing synchronization between multiple databases (think distributed
VCS). Basically, each outdated object on the receiving side is updated
by updating its variables and committing it to the database.

Now there is some required information in those objects which is checked
in the __init__ method of each class. Therefore to create an object from
the remote object, I am skipping the call to __init__ (like e.g. pickle
does).

(Interestingly, pickle creates an empty class first and goes to update
__class__ afterwards. Why?!)

So to create the instances for the mapped objects, I used

instance = MyClass.__new__(MyClass)

as in the attached example. This fails with an attribute error for
"_sa_instance_state". My work around is to use

instance = manager_of_class(MyClass).new_instance()

but I am wondering if this should be needed, especially since the
ClassManager class is not documented. What should I be using instead?

Greetings, Torsten

--
DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
Torsten Landschoff

Office Dresden
Tel: +49-(0)351-4519587
Fax: +49-(0)351-4519561

mailto:torsten.l...@dynamore.de
http://www.dynamore.de

Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
Managing director: Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz

sqlalchemy_new.py

Michael Bayer

unread,
Jun 28, 2011, 10:28:27 AM6/28/11
to sqlal...@googlegroups.com

On Jun 28, 2011, at 3:45 AM, Torsten Landschoff wrote:

> Hi *,
>
> a while ago I noticed a small problem with SQLAlchemy. I was able to
> work around this, but I am still wondering if this should be required.
>
> I am doing synchronization between multiple databases (think distributed
> VCS). Basically, each outdated object on the receiving side is updated
> by updating its variables and committing it to the database.
>
> Now there is some required information in those objects which is checked
> in the __init__ method of each class. Therefore to create an object from
> the remote object, I am skipping the call to __init__ (like e.g. pickle
> does).
>
> (Interestingly, pickle creates an empty class first and goes to update
> __class__ afterwards. Why?!)
>
> So to create the instances for the mapped objects, I used
>
> instance = MyClass.__new__(MyClass)
>
> as in the attached example. This fails with an attribute error for
> "_sa_instance_state". My work around is to use
>
> instance = manager_of_class(MyClass).new_instance()
>
> but I am wondering if this should be needed, especially since the
> ClassManager class is not documented. What should I be using instead?

Instrumentation has to establish state on a new object independent of __new__() - during pickling, the state is restored naturally as __dict__ is restored, during fetch of rows, new_instance() is used, during normal construction, __init__() is used.

class_manager() is documented we'd only need to get new_instance() and the use case documented, seems to me that would be bug fixed.


Torsten Landschoff

unread,
Jun 29, 2011, 2:46:13 PM6/29/11
to sqlal...@googlegroups.com
Hi Michael,

On Tue, 2011-06-28 at 10:28 -0400, Michael Bayer wrote:

> > ClassManager class is not documented. What should I be using instead?
>
> Instrumentation has to establish state on a new object independent of
> __new__() - during pickling, the state is restored naturally as
> __dict__ is restored, during fetch of rows, new_instance() is used,
> during normal construction, __init__() is used.
>
> class_manager() is documented we'd only need to get new_instance() and
> the use case documented, seems to me that would be bug fixed.

Fine with me. Thanks! :-)

Still I wonder why __init__ is still supported when using ORM mapped
classes and __new__ is not. Is there any reason why the latter is harder
to support? Or is it a matter of too little gain (who is using __new__
anyway?) for too much work?

Michael Bayer

unread,
Jun 29, 2011, 3:31:12 PM6/29/11
to sqlal...@googlegroups.com

On Jun 29, 2011, at 2:46 PM, Torsten Landschoff wrote:

> Hi Michael,
>
> On Tue, 2011-06-28 at 10:28 -0400, Michael Bayer wrote:
>
>>> ClassManager class is not documented. What should I be using instead?
>>
>> Instrumentation has to establish state on a new object independent of
>> __new__() - during pickling, the state is restored naturally as
>> __dict__ is restored, during fetch of rows, new_instance() is used,
>> during normal construction, __init__() is used.
>>
>> class_manager() is documented we'd only need to get new_instance() and
>> the use case documented, seems to me that would be bug fixed.
>
> Fine with me. Thanks! :-)
>
> Still I wonder why __init__ is still supported when using ORM mapped
> classes and __new__ is not. Is there any reason why the latter is harder
> to support? Or is it a matter of too little gain (who is using __new__
> anyway?) for too much work?

I'm not sure offhand if __new__() can be wrapped in a monkeypatch the way we do for __init__(), or if so what are the side effects of that, and it also would mean there's no way to create a new instance without ._sa_instance_state being tacked on. Particularly with pickling this is problematic.


Torsten Landschoff

unread,
Jun 29, 2011, 3:59:10 PM6/29/11
to sqlal...@googlegroups.com
On Wed, 2011-06-29 at 15:31 -0400, Michael Bayer wrote:

> I'm not sure offhand if __new__() can be wrapped in a monkeypatch the
> way we do for __init__(), or if so what are the side effects of that,
> and it also would mean there's no way to create a new instance
> without ._sa_instance_state being tacked on. Particularly with
> pickling this is problematic.

Good point, I missed that __new__ might be needed for unpickling.
Thanks!

Reply all
Reply to author
Forward
0 new messages