Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy: How to order query results (order_by) on a relationship's field?

Tags:

Models

from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, ForeignKey from sqlalchemy import Integer from sqlalchemy import Unicode from sqlalchemy import TIMESTAMP from sqlalchemy.orm import relationship  BaseModel = declarative_base()  class Base(BaseModel):    __tablename__ = 'base'    id = Column(Integer, primary_key=True)    location = Column(Unicode(12), ForeignKey("locationterrain.location"), unique=True,)    name = Column(Unicode(45))    ownerid =  Column(Integer,ForeignKey("player.id"))    occupierid =  Column(Integer, ForeignKey("player.id"))    submitid =  Column(Integer,ForeignKey("player.id"))    updateid =  Column(Integer,ForeignKey("player.id"))    owner = relationship("Player",          primaryjoin='Base.ownerid==Player.id',          join_depth=3,          lazy='joined')    occupier= relationship("Player",          primaryjoin='Base.occupierid==Player.id',          join_depth=3,          lazy='joined')    submitter = relationship("Player",          primaryjoin='Base.submitid== Player.id',          join_depth=3,          lazy='joined')    updater= relationship("Player",          primaryjoin='Base.updateid== Player.id',          join_depth=3,          lazy='joined')   class Player(BaseModel):    __tablename__ = 'player'    id = Column(Integer, ForeignKey("guildmember.playerid"), primary_key=True)    name =  Column(Unicode(45)) 

Searching

bases = dbsession.query(Base) bases = bases.order_by(Base.owner.name) 

This doesn't work .... I've searched everywhere and read the documentation. But I just don't see how I can sort my (Base) query on their 'owner' relationship's name.

It always results in:

 AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 'name' 

This must be easy... but I don't see it. Also looked into Comparators, which seemed logical, but I don't see where the query part for the ORDER BY is generated or what I should be returning since everything is generated dynamically. And making a comparator for each of my 'player' relationships to do a simple thing seems over complicated.

like image 383
The Pjot Avatar asked Mar 25 '12 16:03

The Pjot


People also ask

Does SQLAlchemy support batching?

SQLAlchemy supports the widest variety of database and architectural designs as is reasonably possible. Unit Of Work. The Unit Of Work system, a central part of SQLAlchemy's Object Relational Mapper (ORM), organizes pending insert/update/delete operations into queues and flushes them all in one batch.

What does First () do in SQLAlchemy?

Return the first result of this Query or None if the result doesn't contain any row. first() applies a limit of one within the generated SQL, so that only one primary entity row is generated on the server side (note this may consist of multiple result rows if join-loaded collections are present).

What does SQLAlchemy all () return?

As the documentation says, all() returns the result of the query as a list.

What is SQLAlchemy sequence?

Defining Sequences. SQLAlchemy represents database sequences using the Sequence object, which is considered to be a special case of “column default”.


1 Answers

SQLAlchemy wants you to think in terms of SQL. If you do a query for "Base", that's:

SELECT * FROM base 

easy. So how, in SQL, would you select the rows from "base" and order by the "name" column in a totally different table, that is, "player"? You use a join:

SELECT base.* FROM base JOIN player ON base.ownerid=player.id ORDER BY player.name 

SQLAlchemy has you use the identical thought process - you join():

session.query(Base).join(Base.owner).order_by(Player.name) 
like image 94
zzzeek Avatar answered Oct 20 '22 20:10

zzzeek