Как определить mysql auto_increment id нового объекта в контейнере Alchemist

Эта статья раскрывает особый способ получения id объекта, который был добавлен в контейнер последним. Автор: Izak Burger

Alchemist - это продукт zope, который переносит объекты sqlalchemy в zope и позволяет Вам предоставлять контейнеры для этих объектов.

От нас требовали перенаправить пользователя к недавно созданному объекту. Проблема состояла в том, что мы не знали, какой id будет назначен объекту, так как это было сделано базой данных MySQL через использование auto_increment.

Мы заметили, что sqlalchemy предоставляет список last_inserted_ids, но этого было очень трудно добиться. Мы решили воспользоваться менеджером сессии, который является  threadlocal, и функцией Mysql's LAST_INSERT_ID.

При создании нового объекта мы сначала добавили обработчик событий: 

from Products.example.alchemy.license.mapper import license_mapper
from Products.example.alchemy.util import getLastInsertId

def onLicenseAdd(ob, event):
    ...
    context.last_created_id = getLastInsertId(license_mapper, ob)

В приведенном выше фрагменте, context - это родительский контейнер. Атрибут  контейнера last_created_id всегда содержит id объекта, который был создан последним.

Наконец, getLastInsertId выглядит следующим образом: 

from ore.alchemist.manager import get_session

def getLastInsertId(mapper, ob):
    """
    Determine the last inserted id for ob. Two parameters are 
    required:
    mapper: The alchemy mapper for ob
    ob: The uncommited object for which you require a new id
    Note - This will commit ob!
    """
    session = get_session()
    session.flush([ob])
    connection = session.connection(mapper)
    result = connection.execute('SELECT LAST_INSERT_ID()')
    return result.fetchall()[0][0]

Теперь мы можем  реализовать nextURL в контроллере Вида. В Alchemist, nextURL () вызывается для определения места переадресации пользователя: 

from Products.alchemist.browser.formlib import RecordAddForm

class LicenseAddView(RecordAddForm):
    def nextURL(self):
        context = self.context
        last_created_id = context.last_created_id
        return "%s/%s/@@viewlicense" % (context.absolute_url(),/
                                                 last_created_id)

 

По материалам www.upfrontsystems.co.za

Перевод ООО «Комтет» komtet.ru