← Back to team overview

launchpad-dev team mailing list archive

Re: Lower query counts via different code structure

 

I liked this idea when you mentioned it at UDS.

The essential problem here seems to be that in the 'active record'
pattern by the time you get to doing db access, you have lost some of
the context about the overall scope of objects that should be fetched,
and it can be too big or too small.  It seems like you want to move
towards higher-level code having an opinion on what the scope of the
query ought to be.  If a page does too many queries, we'll make sure
the code at that level has a reasonable opinion and is expressing it
clearly.


> context = Context()
> distros = Launchpad.search(context, distro_name='ubuntu')
> branding = distros.get_branding()
> bugs = distros.hot_bugs(limit=20)
> people = bugs.get_subscribers()
> people.update(bugs.get_assignees())
> people.update(bugs.get_reporters())
> branding.update(people.get_branding())
> context.realise()
> distro = None
> for bug in bugs:
>    if bug.distro != distro:
>        distro = bug.distro:
>            show_branding(distro)
>    ...

'update' is already so strongly bound in database code perhaps
'expand' would be better.

My experience with bugs in Python leads me to prefer not to have
objects that can be very different states, as "realize" does, but
rather to construct a new object when we execute the query.  (In
particular recently txrestfulclient had some bugs that would be
tedious to relate, but could have been systematically avoided by not
giving out references to the object until it was actually ready to
use.)  In that case the original group would be a bit like a
specification, and then you'd then do the query and get what is
sometimes called a recordset.

> Evaluation:
>  - lazy as we build out the things we need, then eager on realise().
> We could add a trigger for realize to __iter__ on groups but I think
> it would reduce safety.
>  - realise() could potentially perform multiple queries per group - or
> could use DecoratedResultSet (or similar) to perform a single query. A
> primary point of this interface is to let folk working on performance
> change from single query to multiple query *without changing the
> callers*.

I think getting a clear policy on this is crucial.  If you ever
implicitly do queries, there is the risk of things getting
accidentally slow; on the other hand if you must always explicitly
query perhaps the interface will be tedious.  Of course there is a lot
of prior art.

-- 
Martin



Follow ups

References