SqlAlchemy prev / next accessors? - PullRequest
       2

SqlAlchemy prev / next accessors?

6 голосов
/ 05 декабря 2010

Есть ли способ получить предыдущие / следующие записи из запроса SqlAlchemy?Примерно так:

record.id
record.next.id
record.prev.id

Я мог бы сам добавить методы prev / next к каждой модели, но мне интересно, есть ли уже какой-то автоматический способ, который я упустил.Рассматриваемое веб-приложение написано на Pylons.

Редактировать: Это, вероятно, грязный хак, но он работает.Я импортировал объект Sqlalchemy Session в свою модель и сделал это:

def next(self):
    return Session.query(Blog).filter(Blog.id > self.id).order_by(Blog.id).first()

def prev(self):
    return Session.query(Blog).filter(Blog.id < self.id).order_by(desc(Blog.id)).first()

Ответы [ 3 ]

0 голосов
/ 26 декабря 2014

Плюс 1 и Минус 1 в последней записи базы данных иногда будут работать. Что делать, если вы удалите пару последних записей. Следующий идентификатор не будет плюс один или минус один на последнем идентификаторе. Это не сессия, это MySQL вещь. Чтобы получить следующий идентификатор, вам нужно выполнить несколько запросов к информационной схеме, например так.

q = "SELECT auto_increment FROM INFORMATION_SCHEMA.TABLES WHERE table_name='table_name'"
a = s.execute(q) #where s is sqlalchemy session

for b in a:

   print b
   print b[0]

, который даст вам что-то вроде: (163459L,) 163459

В моем случае это правда.

А для предыдущей записи вы всегда можете сделать .first () для вашей последней записи Это предыдущий рекорд.

0 голосов
/ 03 июня 2016

Вот то, что я использую, чтобы получить следующий / предыдущий из объекта, используя sqlalchemy.Идея состоит в том, чтобы получить row_number объекта из начального списка и выполнить другой запрос со смещением +/- 1.

Я использую подзапрос с ROW_NUMBER ( Как использовать ROW_NUMBER ()? ) для получения row_number из исходного запроса:

row_number = func.row_number().over(order_by=orders).label("row_number")
row_number_subquery = self.getlistquery(columns=chain([row_number], pk_columns)).subquery()

Затем я присоединяюсь к модели по первичным ключам:

join_clause = [getattr(row_number_query.c, pk.key) == getattr(model, pk.key) for pk in pk_columns]

Я фильтрую по первичным ключамobject:

filter = [getattr(model, pk.key) == pk_values[index] for index, pk in enumerate(pk_columns)]

Я создаю последний запрос для получения смещения объекта:

offset = db.session.query(row_number_subquery).join(model, *join_clause).filter(*filter).first()

Тогда элемент содержит offset, необходимый для следующего, или offset-2 для предыдущего.(начиная с 1 для row_number и 0 для смещения)

self.getlistquery().offset(offset)
0 голосов
/ 22 июня 2011

Я хотел бы предложить выполнить исходный запрос, запрашивающий -1 и +1, чтобы вы могли легко получить идентификаторы без необходимости запуска другого запроса, что экономит время при обработке на сервере SQL.определенно работает, но требует дополнительных двух запросов.Вы даже можете сделать это подзапросом, чтобы, если вы просто хотите извлечь одну строку и добавить к ней предыдущий / следующий, эти данные сохраняются в столбце, созданном подзапросом.

...