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.