In theory, I'm not against such an approach, but practically, this
would be a major refactoring of the code and I don't have time for
that and I guess the soaplib guys don't have either.
What would be possible though (and much more realistic) is to allow
people to optionally use Elixir without its metaclass. Of course, in
that case you'd have to somehow initialize the class yourself. If we
do that you could place that Elixir "init thing" into your own
metaclass inheriting from soaplib's metaclass. Not sure it'd work
(I've actually never played with metaclass inheritance). Or if soaplib
does the same, you could simply create your own metaclass and call
both init methods in turn.
On the Elixir side, here's a example of how it'd look like:
class Test(object):
has_field('name', String(30))
elixir.setup_entity(Test)
Hope this helps,
On 6/27/07, Paul Snively <[EMAIL PROTECTED]> wrote:
> Hi folks. First, let me thank you all for these great tools, Elixir and
> soaplib. They're both immeasurably helpful to our product.
>
> Unfortunately, though, they're two great tastes that don't taste great
> together. Specifically, a class that attempts to inherit from both Elixir's
> Entity class and soaplib's ClassSerializer class fails because both Entity
> and ClassSerializer rely on helpful metaclasses, and as we all learned from
> "Highlander," there can be only one.
>
> What makes this inability to compose metaclasses particularly painful in
> this case, though, is that they have extremely similar goals: mutatis
> mutandis, both are concerned with allowing the user to specify attributes
> of
> the class that the metaclass is of, as well as some metadata about their
> types. This metadata is sufficient to support a transformation on the graph
> of instances of the class that the metaclass is of. In the case of Elixir,
> the transformation is between the object graph and the kinda-sorta set
> theory of a SQL database schema; in the case of soaplib, the transformation
> is between the object graph and the textual serialization of the XML
> infoset
> representing a SOAP envelope. The Elixir Entity ends up with a "table"
> attribute containing this metadata, constructed using the "has_one,"
> "has_many," "belongs_to," and "has_and_belongs_to_many" statements; the
> soaplib ClassSerializer ends up with a "soap_members" attribute containing
> this metadata, constructed using the "types" nested class.
>
> It would seem potentially beneficial to attempt to derive a uniform API
> for:
>
> * Describing some subset of the attributes of a class and their types.
> * Given an object graph with such descriptions, perform transformations on
> the graph:
> incrementally or
> atomically
> * Process nodes based on both their value and type metadata
> * Support lifecycle customization (before transformation, before node,
> after node, after transformation)
>
> This really just sounds like a combination of visitor and observer
> patterns,
> and possibly the strategy pattern for processing the nodes. Elixir would
> provide a SQLization strategy; soaplib would provide an XMLization
> strategy.
> Of course, this glosses over a great many details, such as how each system
> would attach system-specific metadata, e.g. "required" for Elixir or
> "min/max" for soaplib. One approach might be to leverage decorators, since
> decorators compose over the thing they decorate.
>
> Any thoughts?
>
> In the meantime, does anyone have any concrete advice on how to use Elixir
> and soaplib together? Ben Bangert suggested having my class only inherit
> from Entity, and then adding ClassSerializer manually:
>
> class Foo(Entity):
> ...
> Foo.__bases__ = Foo.__bases__ + (ClassSerializer,)
>
> Naturally, actually attempting to use Foo in normal soaplib practice fails
> because no initialization on the metaclass has been done--the metadata that
> ClassSerializerMeta.__init__ creates obviously hasn't been created--so I
> tried:
>
> class Foo(Entity):
> ...
> Foo.__bases__ = Foo.__bases__ + (ClassSerializer,)
> ClassSerializerMeta.__init__(Foo, "Foo", [], {})
>
> This complains that __init__ wants an instance of ClassSerializerMeta and
> instead is getting an instance of EntityMeta. So I tried:
>
> class Foo(Entity):
> ...
> Foo.__bases__ = Foo.__bases__ + (ClassSerializer,)
> _old = Foo.__metaclass__
> Foo.__metaclass__ = ClassSerializerMeta
> ClassSerializerMeta.__init__(Foo, "Foo", [], {})
> Foo.__metaclass__ = _old
>
> Python isn't fooled one bit: __init__ still complains that it's getting an
> instance of EnityMeta, not ClassSerializerMeta. At this point I decided
> that
> this was getting too ugly, talked to Ben Bangert about it some more, and he
> encouraged me to discuss it here. So here it is.
>
> Many thanks and best regards,
> Paul Snively
--
Gaƫtan de Menten
http://openhex.org
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"SQLElixir" 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/sqlelixir?hl=en
-~----------~----~----~----~------~----~------~--~---