Hello.

Would it be possible to make these two forms

    session.query(cls).options(
        subqueryload(cls.foos),
        subqueryload(cls.foos, Foo.bar),
    )

and

    session.query(cls).options(
        subqueryload_all(cls.foos, Foo.bar)
    )

completely equivalent, i.e. subqueryload_all being just a shortcut of the former
if the paths have the above pattern (i.e. if one subqueryload is subsumed by
another)?

My motivation: I have a rather complex function (see below) used in several
contexts that returns Query.options for class Subject. The code is written to
eliminate duplication, but the current 'suboptimal' behaviour of subqueryload
(when compared to subqueryload_all) forces me to implement (and maintain)
several independent versions of this function.

Or am I missing something that could help me (perhaps rephrase the loads
differently)?

The function (on class Subject) currently looks like this:

    @classmethod
    def fetch_options(
                cls,
                prefix=None, alias=None,
                fetch_name=True,
                fetch_personal=True, fetch_corporate=True,
                use_joinedload=True, use_innerjoin=True,
                fetch_address=False,
                fetch_tags=False,
                fetch_all=False
        ):
        """Fetch subject info. Basic usage (note the '*'!):
            session.query(Subject).options(*Subject.fetch_options())
        Arguments:
        * prefix - Use if Subject is not queried directly, e.g.:
            session.query(Partner).options(
                *Subject.fetch_options(prefix=[Partner.subject])
            )
        * alias - Specify if necessary, e.g.:
            subj_alias = aliased(Subject)
            session.query(subj_alias).options(
                *Subject.fetch_options(alias=subj_alias)
            )
        * fetch_name - Fetch everything for Subject.display_name(partner). This
        is the default.
        * fetch_address - Fetch addresses-related info. Implies fetch_name.
        * fetch_tags - Fetch tag-related info. Can be used on its own.
        * fetch_personal - Set to False to supress fetching of any info about
        persons.
        * fetch_corporate - Set to False to supress fetching of any info about
        corporations.
        * fetch_all - Shortcut that implies all above.
        * use_joinedload - joinedload() is used by default to fetch all 1:1
        relationships. If prefix contains 1:N relationship(s), set this to
        False and subqueryload() will be used instead.
        * use_innerjoin - One of fetch_personal or fetch_corporate MUST be
        True. If only one is set, all joinedload() will be INNER by default.
        Set this to False to force the use of OUTER.
        """
        from zfp.model.contact import Contact, ContactPersonal, ContactCorporate
        from zfp.model.tag import TagSubject
        if fetch_all:
            fetch_name = True
            fetch_personal = True
            fetch_corporate=True
            fetch_address=True
            fetch_tags=True
        elif fetch_address:
            fetch_name = True
        assert fetch_personal or fetch_corporate
        use_innerjoin = use_innerjoin and not(fetch_personal and 
fetch_corporate)
        if use_joinedload:
            def load_op(*args):
                return joinedload(*args, innerjoin=use_innerjoin)
        else:
            def load_op(*args):
                return subqueryload(*args)
        if prefix is None:
            prefix = []
        if alias is None:
            alias = cls
        options = []
        if fetch_name:
            options.extend([
                subqueryload(*prefix + [alias.contacts]),
            ])
            if fetch_personal:
                options.extend([
                    load_op(*prefix + [alias.subject_personal]),
                    subqueryload(*prefix + [alias.contacts,
Contact.contact_personal]),
                ])
            if fetch_corporate:
                options.extend([
                    load_op(*prefix + [alias.subject_corporate]),
                    subqueryload(*prefix + [alias.contacts,
Contact.contact_corporate]),
                ])
        if fetch_address:
            if fetch_personal:
                options.extend([
                    load_op(*prefix + [alias.subject_personal,
SubjectPersonal.address]),
                    subqueryload(*prefix + [alias.contacts,
Contact.contact_personal, ContactPersonal.contact_address]),
                    subqueryload(*prefix + [alias.contacts,
Contact.contact_personal, ContactPersonal.permanent_address]),
                ])
            if fetch_corporate:
                options.extend([
                    load_op(*prefix + [alias.subject_corporate,
SubjectCorporate.address]),
                    subqueryload(*prefix + [alias.contacts,
Contact.contact_corporate, ContactCorporate.address]),
                ])
        if fetch_tags:
            options.extend([
                subqueryload_all(*prefix + [alias.tag_subjects, 
TagSubject.tag]),
            ])
        if fetch_all:
            options.extend([
                subqueryload(*prefix + [alias.contacts, Contact.phones]),
                subqueryload(*prefix + [alias.contacts, Contact.emails]),
            ])
        return options


Thank you,

Ladislav Lenart

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to