Кроме того, ключевая концепция
Единица работы шаблона заключается в том, что это
организует полный список всех
Операторы INSERT, UPDATE и DELETE
который будет выпущен, а также
порядок, в котором они испускаются,
прежде чем что-то случится. Когда
before_insert () и after_insert ()
Хуки событий называются, эта структура
был определен, и не может быть
изменилось никак.
документация для before_insert () и
before_update () упоминает, что
на этот план нельзя повлиять
точка - только отдельные атрибуты на
объект под рукой, и те, которые
еще не были вставлены или обновлены,
могут быть затронуты здесь. Любая схема
который хотел бы изменить флеш
План должен использовать
SessionExtension.before_flush.
Тем не менее, есть несколько способов
выполняя то, что вы хотите здесь
без изменения плана сброса.
Самое простое, что я уже
предложил. использование
MapperExtension.before_insert () на
«Пользовательский» класс и набор
user.question_count =
LEN (user.questions). Это предполагает
что вы мутируете
Коллекция user.questions, а не
работа с Question.user для
установить отношения. если ты
случилось использовать "динамический"
отношения (что не так
здесь), вы бы вытащить историю для
user.questions и подсчитать, что
были добавлены и удалены.
Следующий способ - сделать
что вы думаете, что вы хотите здесь, то есть
реализовать after_insert в вопросе,
но испускают оператор UPDATE
сам. Вот почему «связь»
один из аргументов к мапперу
методы расширения:
def after_insert(self, mapper, connection, instance):
connection.execute(users_table.update().\
values(question_count=users_table.c.question_count +1).\
where(users_table.c.id==instance.user_id))
Я бы не предпочел такой подход, так как
это довольно расточительно для многих новых
Вопросы добавляются в один
Пользователь. Так что еще один вариант, если
На User.questions нельзя положиться
и вы хотели бы избежать многих специальных
ОБНОВЛЕНИЕ заявления, на самом деле
повлиять на план сброса с помощью
SessionExtension.before_flush:
Класс
MySessionExtension (SessionExtension):
def before_flush (self, session, flush_context):
для obj в session.new:
если isinstance (объект, вопрос):
obj.user.question_count + = 1
for obj in session.deleted:
if isinstance(obj, Question):
obj.user.question_count -= 1
Объединить «совокупный» подход
метод before_flush с
Подход "испускай SQL сам"
метод after_insert (), вы можете
также используйте SessionExtension.after_flush,
посчитать все и испустить
единый массовый оператор UPDATE со многими
параметры. Мы, вероятно, хорошо в
царство излишества для этого конкретного
ситуация, но я привел пример
такой схемы в Пиконе в прошлом году,
который вы можете увидеть на
http://bitbucket.org/zzzeek/pycon2010/src/tip/chap5/sessionextension.py
.