On 08/30/2010 16:06, Michael Bayer wrote:

On Aug 30, 2010, at 5:59 AM, Julien Cigar wrote:

Hello,

Quick question, is there a way to use .with_polymorphic() on a Query with 
existing criterion ?

I have the case where I have 2 queries with the same criteria where one of 
those queries is a count(*). I would like to avoid multiple LEFT JOIN because 
criteria in the count(*) query because they are not necessary (criteria relate 
to the base class).


with_polymorphic() is a pretty limited feature at the moment which is why it 
only works against a single entity and only works up front.


limited.. but pretty useful in my case :)

I haven't added this to the main docs but the strategy to get a polymorphic 
query of any style is to use the individual Table objects and construct the 
joins as needed, like:

sess.query(Person).join((engineers_table, Person.id==engineers_table.c.id))...

.outerjoin(), no ?


very often if i just need information against the subclass, I'll leave out the 
base entirely.  It's all about placing the minimal number of tables in the FROM 
clause:

sess.query(engineers_table.c.id).join((machine_table, 
engineers_table.c.id==machine_table.c.engineer_id))...



In fact I'm writing a CMS where I allow the user to select which subclasses is queried within a given container, this allow the use to add default ordering of a container, apply filters, etc

I ended with something like (I use the .whereclause of the first query):

q = model.Content.query.published().in_container(id)

( ... )

c.count_filtered = q.count()

q2 = model.Content.query.with_polymorphic_content(id).\
     filter(q.whereclause)

I have a custom Query object with the following:

    @staticmethod
    def get_polymorphic_content(src):
        if not isinstance(src, Content):
            src = Content.query.get(src)

        if not src.polymorphic_loading:
            # TODO : default polymorphic loading strategy ..
            return None
        elif src.polymorphic_loading == 'y':
            return '*'
        elif src.polymorphic_loading == 'c':
            polymorphic_types = [i.id for i in src.polymorphic_children]
            polymorphic_map = orm.class_mapper(Content).polymorphic_map
            return [polymorphic_map[i].class_ for i in \
                    polymorphic_types]
        else:
            return None

    def with_polymorphic_content(self, src):
        cls = self.__class__.get_polymorphic_content(src)
        return self if not cls else self.with_polymorphic(cls)

Thanks,
Julien




Thanks,
Julien

--
No trees were killed in the creation of this message.
However, many electrons were terribly inconvenienced.

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

<jcigar.vcf>



--
No trees were killed in the creation of this message.
However, many electrons were terribly inconvenienced.

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

<<attachment: jcigar.vcf>>

Reply via email to