Naota
Апрель 11, 2009 14:26:11
Есть запрос query(Uer.id, User.name, Address.city_id, Address.street_id).join(Address). Как можно взять столбец в виде объекта(Uer.id или Address.city_id) по индексу? Что бы было понятно, это нужно для сортировки. Что-то типа такого: query(Uer.id, User.name, Address.city_id, Address.street_id).join(Address).order_by(q) и сортируется по User.name.
Naota
Апрель 11, 2009 17:47:07
Я немного порылся в коде и нашел метода _entities + desc из sqlalchemy.sql.expression. И получается запрос:
from sqlalchemy.sql.expression import desc
items = query(Uer.id, User.name, Address.city_id, Address.street_id).join(Address)
items = items.order_by(desc(items._entities[1]))
Итадакимас ^_^
bw
Апрель 12, 2009 02:52:15
А чем .order_by(User.id.desc()) не устраивает?
Или ты заранее не знаешь, какие будут поля в запросе?
p.s. Я бы не рекомендовал использовать это скрытое поле. Если тебе заранее не известны атрибуты, по которым выполняется запрос, лучше передавай их (кому там это надо) отдельно от объекта Query.
..bw
Андрей Светлов
Апрель 12, 2009 03:57:09
bw
+1
Naota
Апрель 12, 2009 10:13:19
bw Не известно. Я использую плагин к jQuery jqGrid. Там есть сортировка и можно указывать все это, но занимает много строк, для сокращения я сделал функцию, которая все это вычисляет легко и просто :)
bw
Апрель 13, 2009 03:42:35
Ты хоть проверяешь объекты, что бы они были sqlalchemy.orm.query._ColumnEntity? И предпринимаешь действия, если что-то не так?
Например, протоколируешь ошибку, возвращаешь результат без сортировки, сигналишь пользователю, что что-то не так.
..bw
Naota
Апрель 16, 2009 16:23:56
где проверять это? сигналить там не нужно, если только хакерам :)
JS передает номер столбца, по ней и делается сортировка.
PooH
Апрель 17, 2009 05:50:38
Naota
JS передает номер столбца, по ней и делается сортировка.
Я тоже использовал jqGrid. Никаких извращений с индексом не понадобилось. Написал виджет к TurboGears для вывода грида и простенький декоратор в котором делается и сортировка и поиск и пейджинатор
Naota
Апрель 17, 2009 20:48:22
Я сделал это так:
def items(self):
items = sas.query(...)
records, total, items = GridParams(items, p)
rows = []
for i in items:
rows.append(u'{id:"%s", cell:["%s","%s","%s","%s","%s","%s"]}'%
(i[0],i[0],i[1],i[2],i[3],i[4],i[5]))
return u'''{total:%i,page:%i,records:%i,rows:[%s]}'''%(total,p.page,records,','.join(rows))
def GridParams(items, p):
records = items.count()
if records == 0: return 0, 0, items
total = records/p.rows
if records%p.rows != 0: total += 1
if p.sidx >= len(items._entities): return
item = items._entities[p.sidx]
if p.sord == 'desc': item = desc(item)
items = items.order_by(item).offset((p.page-1)*p.rows).limit(p.rows)
return records, total, items
В
p содержатся параметры запроса:
sord,sidx,rows,page.
А вы
PooH как сделали?
Naota
Апрель 18, 2009 21:16:15
Новый вариант:
def items(self):
items = sas.query(...)
sf = '"%(id)s","%(fio)s","%(part)s","%(stones)s","%(note)s","%(cost)s","%(count)s",""'
return TableToJson(items, p, sf)
class RowsToJson(dict):
def __init__(self, items, sf):
self.columns = self._to_dict(items)
self.cells = None
self.result = ','.join([sf%self(i) for i in items])
dict.__init__(self)
def __getitem__(self, label):
item = self.cells[self.columns[label]]
if type(item) in (str, unicode):
item = item.replace('"','\\"')
return item
def __str__(self):
return self.result
def __call__(self, cells):
self.cells = cells
return self
def _to_dict(self, items):
d = {}
for i, c in enumerate(items._entities): d[c.column.key] = i
return d
def TableToJson(items, p, sf):
records = items.count()
if records == 0: '{total:0,page:0,records:0}'
total = records/p.rows
if records%p.rows != 0: total += 1
if p.sidx >= len(items._entities): return
item = items._entities[p.sidx]
if p.sord == 'desc': item = desc(item)
items = items.order_by(item).offset((p.page-1)*p.rows).limit(p.rows)
rows = RowsToJson(items, '{id:"%(id)s", cell:['+sf+']}')
return '{total:%i,page:%i,records:%i,rows:[%s]}'%(total,p.page,records,rows)
Есть какие замечания и идеи?