On 29.10.2011 00:10, Michael Bayer wrote:

On Oct 28, 2011, at 3:16 PM, Burak Arslan wrote:


the link I provided has both the client and server implementations to reproduce the issue, maybe you didn't scroll up?

Did not scroll up, no. So looking at the sample code here, it's entirely a mystery to me how this is even supposed to work; the mappings are not recreated in any way I'm familiar with in ws_client.py.

they are not created in the client, the client is just there to painlessly trigger the server-side code, that's all.

It does appear like there's some major magic going on in rpclib/model/table.py to accomplish this. One thing I'd note is that its usually better not to rely on declarative, which is only syntactical sugar, to get information about a mapping - the Table and mapper() structure contain all the information. Basing this system on declarative for introspection is already brittle.


there's actually no magic at all (it's just ~50 lines). rpclib's metaclass processes the class definition to create its own data structure and just gets out of the way. have a look: https://github.com/arskom/rpclib/blob/master/src/rpclib/model/table.py#L111

your remarks are noted, but it's the same syntactic sugar that i want to make available in rpclib, so i guess i will have to stick with declarative.

Anyway whatever magic in rpclib is somehow recreating the mappings in a new process isn't doing the job correctly. It's creating two Patient classes with mismatched state. The codepath being reached is only present for the edge case that a subclass of a superclass is not mapped, but then in this case the class manager is doubled up somehow.


mappers are not recreated in other processes or anything. again, rpclib's TableModelMeta just parses cls_dict and calls DeclarativeBaseMeta.__new__, that's all.

so, every declarative child as it own class manager, it's not shared between types? how and where is it created?

Usually when I've dealt with RPC types of systems, the classes that are used on the client are statically available, not dynamically reconstructed - that might be a much more reliable approach here.


it is statically available via the wsdl. the wsdl is automatically generated on the server side once every time the server is launched and cached forever. the client only parses that wsdl file, it knows nothing about how those objects are stored.

think of wsdl as a C++ header file serialized to xml. (yes it's very messy :))

Here's how to reproduce:

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base

Base= declarative_base()

class A(Base):
    __tablename__ = "a"

    id = Column(Integer, primary_key=True)

class B(A):
    # this just means, "dont map the class".
    # A is mapped but B is not
    __abstract__ = True

B._sa_class_manager = A._sa_class_manager
B()




um, this doesn't crash at all here, are you sure you didn't miss something ?
i can do a "print B()"

<__main__.B object at 0x030C7C10>

this can be all i need to track down this problem.

thank you for your time.

best regards,
burak

--
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.

Reply via email to