On Nov 19, 2011, at 7:42 PM, Hector Blanco wrote:
> As you can see, only two of those classes have a "_name" attribute.
>
> What I'd like to know is if I can set an "order_by" in the
> BaseObject._children relationship that does the following:
> 1) Sort by type, but not the default ordering. If I set up (in
> _children) the order_by to order by _polymorphicIdentity (by the
> discriminator), I'd get instances of type "Element1", then instances
> of "Element2" and finally, from "Element3". I don't want that. I need
> to get "Element1", "Element3" and finally, "Element2".
> 2) Sort by name if the child has a name. If it doesn't, leave it with
> the 'special' _polymorphicIdentity described above if the child class
> doesn't have a _name attribute.
two things. First off, you have collection_class=set with an order_by.
You'll want to change that as sets aren't ordered.
next thing. Don't think about mappers and classes here, think of the SQL.
You're basically asking for a query like this:
SELECT * from base_objects
LEFT OUTER JOIN elements_1 ON <onclause>
LEFT OUTER JOIN elements_2 ON <onclause>
LEFT OUTER JOIN elements_3 ON <onclause>
ORDER BY
CASE
WHEN base_object._polymorphic_identity='Element1' THEN 'A'
WHEN base_object._polymorphic_identity='Element3' THEN 'B'
WHEN base_object._polymorphic_identity='Element2' THEN 'C'
END,
CASE
WHEN base_object._polymorphic_identity='Element1' THEN
elements_1.name
WHEN base_object._polymorphic_identity='Element2' THEN
elements_2.name
ELSE NULL
END
This is assuming you wanted to sort by both the polymorphic type as well as the
name; it wasn't clear if you wanted to sort just by name with type as a
fallback instead. You'd put the first CASE into the ELSE clause of the second
for that.
So yes, of course you can set up the mappings to work this way, though it would
be tedious to get it working, as the order_by needs to be derived from all
subtables. A key issue as well is that its not really possible to use a
different "with_polymorphic" in the relationship() as that of the mapper by
itself, which means the LEFT OUTER JOIN business above would be emitted in all
cases, unless *perhaps* a secondary mapper were used but I really don't know
that those can be configured polymorphically like that. So at the mapping
level you could barely get this going and it would be pretty scary looking.
Beyond that, it would add an enormous amount of complexity to your SQL queries
and perform quite poorly as LEFT OUTER JOIN optimizes pretty badly. Complex
queries derived from the core here would produce very large, multi-page queries
as this is a recursive structure onto itself already. A schema like this
coupled with the ordering requirement would only be suitable for small to
medium scales of data with only modest performance.
Given all that, it would be my recommendation that you do the sorting in
Python. Add an __lt__() method to your classes that defines this sorting based
on attributes, then add a @property-style accessor to BaseObject that just uses
sorted(self._children). That way you could even keep your
collection_class=set on the _children relationship itself. The mapping goes
back to being simple, or at least as simple as the "joined" case calls for.
>
> I don't even know if that's possible.
> Because of certain dependencies, I can't use SqlAlchemy 0.7.x yet. I
> am using 0.6.8
>
> Thank you very much in advance!
>
> --
> 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.
>
--
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.