11"""Provide the Query class.
22"""
33
4- from collections import OrderedDict
54import re
65from warnings import warn
76from collections .abc import Mapping
@@ -277,7 +276,7 @@ def _dosubst(self, obj, subst, addas=True):
277276
278277 def _get_subst (self ):
279278 if self ._subst is None :
280- joinattrs = ( set ( self .order . keys ()) |
279+ joinattrs = ( self ._order_attrs |
281280 set (self .conditions .keys ()) |
282281 set (self .attributes ) )
283282 self ._subst = self ._makesubst (joinattrs )
@@ -403,15 +402,12 @@ def setOrder(self, order):
403402 allow a JPQL function in the attribute.
404403 """
405404 self ._subst = None
406- # Note: with Python 3.7 and newer we could simplify this using
407- # a standard dict() rather than an OrderedDict().
408- self .order = OrderedDict ()
405+ self .order = []
409406
410407 if order is True :
411408
412- for a in self .entity .getNaturalOrder (self .client ):
413- item = OrderItem (a )
414- self .order [item .attr ] = item
409+ self .order = [ OrderItem (a )
410+ for a in self .entity .getNaturalOrder (self .client ) ]
415411
416412 elif order :
417413
@@ -435,9 +431,7 @@ def setOrder(self, order):
435431
436432 if rclass is None :
437433 # the item is an attribute, use it right away.
438- if item .attr in self .order :
439- raise ValueError ("Cannot add %s more than once" % item .attr )
440- self .order [item .attr ] = item
434+ self .order .append (item )
441435 else :
442436 # attr is a related object, use the natural order
443437 # of its class.
@@ -446,11 +440,7 @@ def setOrder(self, order):
446440 "to a related object: %s" % obj )
447441 for ra in rclass .getNaturalOrder (self .client ):
448442 rattr = "%s.%s" % (item .attr , ra )
449- if rattr in self .order :
450- raise ValueError ("Cannot add %s more than once"
451- % rattr )
452- ritem = OrderItem (rattr , cloneFrom = item )
453- self .order [ritem .attr ] = ritem
443+ self .order .append (OrderItem (rattr , cloneFrom = item ))
454444
455445 def addConditions (self , conditions ):
456446 """Add conditions to the constraints to build the WHERE clause from.
@@ -519,6 +509,10 @@ def setLimit(self, limit):
519509 else :
520510 self .limit = None
521511
512+ @property
513+ def _order_attrs (self ):
514+ return { item .attr for item in self .order }
515+
522516 @property
523517 def select_clause (self ):
524518 """The SELECT clause of the query.
@@ -588,8 +582,8 @@ def order_clause(self):
588582 """
589583 if self .order :
590584 subst = self ._get_subst ()
591- orders = [ self . order [ a ]. formatstr % self ._dosubst (a , subst , False )
592- for a in self .order . keys () ]
585+ orders = [ item . formatstr % self ._dosubst (item . attr , subst , False )
586+ for item in self .order ]
593587 return "ORDER BY " + ", " .join (orders )
594588 else :
595589 return None
0 commit comments