Ticket #1582 (closed enhancement: fixed)

Opened 8 months ago

Last modified 6 months ago

[PATCH] Paginate should allow ordering by attributes from related objects (SA Query)

Reported by: roger.demetrescu Assigned to: roger.demetrescu
Priority: normal Milestone: 1.0.4
Component: TurboGears Version: 1.0.4b1
Severity: normal Keywords: paginate sqlalchemy query
Cc:

Description

The current implementation from paginate + Query (sqlalchemy) doesn't allow ordering by attributes/properties from related objects.

Eg.: suppose we have the following model:

occupations_table = Table('occupations', metadata,
    Column('occupation_id', Integer, primary_key=True),
    Column('occupation_name', String(20)),
)


users_table = Table('users', metadata,
    Column('user_id', Integer, primary_key=True),
    Column('user_name', String(20)),
    Column('occupation_id', Integer, ForeignKey("occupations.occupation_id")),
)


addresses_table = Table('addresses', metadata,
    Column('address_id', Integer, primary_key=True),
    Column('user_id', Integer, ForeignKey("users.user_id")),
    Column('street', String(50)),
    Column('city', String(40))
)


class Occupation(object):
    pass

class User(object):
    pass

class Address(object):
    pass


mapper(Occupation, occupations_table)

mapper(User, users_table, properties={
    'occupation' : relation(Occupation, lazy=False)
})

mapper(Address, addresses_table, properties={
    'user' : relation(User, backref='addresses', lazy=False)
})

We should be able to have Paginate ordering a Query(Address) by:

  • street
  • city
  • user.user_name
  • user.occupation.occupation_name

See also the following thread on ML: http://tinyurl.com/2dpqvt

Attachments

sorting.patch (2.4 kB) - added by roger.demetrescu on 09/25/07 23:01:51.
demo.zip (87.7 kB) - added by roger.demetrescu on 09/25/07 23:02:41.
A demo project

Change History

09/25/07 23:01:51 changed by roger.demetrescu

  • attachment sorting.patch added.

09/25/07 23:02:41 changed by roger.demetrescu

  • attachment demo.zip added.

A demo project

10/19/07 15:17:22 changed by roger.demetrescu

  • status changed from new to closed.
  • resolution set to fixed.

Commited at [3525] and [3526].

10/30/07 13:51:13 changed by roger.demetrescu

  • status changed from closed to reopened.
  • resolution deleted.

The current patch (already applied) doesn't handle backrefs. We should change the code:

mapper.properties.get(propname)

into:

mapper.get_property(propname, raiseerr=False)

or even:

mapper.get_property(propname, resolve_synonyms=True, raiseerr=False)

For more info, take a look at: http://tinyurl.com/38w4l5

(follow-up: ↓ 4 ) 11/01/07 18:05:34 changed by joelpearson

Thanks, Roger! This patch greatly improves the usefulness of paginate.

It worked best for me once I included the change suggested in the previous comment:

mapper.get_property(propname, resolve_synonyms=True, raiseerr=False)

Without "resolve_synonyms=True", mapper synonyms didn't work. With it, everything works as expected.

(in reply to: ↑ 3 ) 11/01/07 19:21:01 changed by roger.demetrescu

Replying to joelpearson:

Without "resolve_synonyms=True", mapper synonyms didn't work. With it, everything works as expected.

Hei Joel...

Thanks for your feedback... I'll commit this change as soon as I finish writing paginate tests.

11/17/07 08:54:10 changed by roger.demetrescu

  • owner changed from anonymous to roger.demetrescu.
  • status changed from reopened to new.

11/18/07 19:17:09 changed by roger.demetrescu

One more reason to start using mapper.get_property() instead of mapper.properties.get(): SQLAlchemy 0.4.1 now raises this exception when we try to use the mapper.properties.get():

NotImplementedError: Public collection of MapperProperty 
objects is provided by the get_property() and iterate_properties accessors.

11/18/07 20:36:52 changed by roger.demetrescu

  • status changed from new to closed.
  • resolution set to fixed.

Fixed in [3716] and [3717].