2013-06-01 5 views
6

При использовании более сложных, иерархических моделей с различными настройками, как обрабатывать каскадные удаления, довольно сложно заранее выяснить, что именно будет делать с базой данных delete().Узнайте, что будет удалено

Я не мог найти способ получить эту информацию («Эй, SQLAlchemy, что будет удалено, если я удалю этот объект там?») из SQLAlchemy. Реализация этого сама по себе на самом деле не кажется вариантом, поскольку это рано или поздно приведет к ситуации, когда мои предсказания и фактические последствия delete() отличаются, что было бы очень ... неприятно для пользователя.

+0

Зачем вам нужно знать? Если вы правильно разработали схему, каскадные удаления будут «делать правильные вещи» - удаление пользователя удалит все строки, связанные с этим пользователем. Может быть, что вы действительно хотите, это «удаленный» столбец, который вы установили в true вместо фактического удаления данных? – Seth

+0

@ dom0 Я думаю 'session.deleted' и установка' session.autoflush = False' должен позволить вам проверять, какие объекты будут удалены перед фиксацией. – Salem

+0

@Seth OP не спрашивал, будет ли ORM делать правильные вещи, они хотели знать, что * будет удалено. И знание того, что собирается быть удалено, НЕОБХОДИМО полезно (я не могу себе представить, почему вы так не считаете). – Colleen

ответ

0

Я задал этот вопрос в списке рассылки SQLAlchemy в
и Michael Bayer explained the possible options (Большое спасибо еще раз :-):

Единственные удалений, которые не присутствуют в session.deleted до вровень являются те, которые произойдут, потому что конкретный объект является «сиротой» и объектами, которые будут удалены в результате каскада у этой сироты.

Таким образом, без учета сирот session.deleted сообщает вам все, что нужно удалить.

Чтобы взять детей-сирот во внимание, необходимо пройти через все отношения, как это делает единица работы, ища объекты, которые в настоящее время являются сиротами (есть функция API, которая скажет вам об этом - если объект считается «сиротой» по любой атрибут, который ссылается на него с помощью каскада delete-orphan, считается «сиротой»), а затем пересекает отношения этих сирот, считая их помеченными как «удаленные», а затем снова выполняет все правила для тех, кто недавно - удаленные объекты.

Система прямо сейчас реализована с помощью orm/dependency.py. Наверное, нетрудно буквально запустить единицу рабочего процесса на сеансе, обычно, но просто не испускать SQL, это даст вам окончательный план флеша. Но это дорогостоящий процесс, который я бы не хотел постоянно звонить.

Функция здесь сложно здесь, потому что прецедент не ясен. Знание того, что будет удалено, в основном требует, чтобы половина процесса флеша фактически продолжалась. Но вы уже можете реализовать события внутри самого процесса flush, наиболее непосредственно перед событиями before_delete() и after_delete(), которые гарантированно поймают все. Таким образом, обоснование новой функции, которая в основном работает на половину флеша, прежде чем вы просто сделаете флеш в любом случае и можете просто помещать события внутри нее, неясно.

Я предполагаю, что большой вопрос: «когда вы называете это».

Простая система заключается в том, чтобы добавить новое событие «flush_plan_complete», которое поместит вас в флеш(), как только будет собран полный план, но до того, как возникнет какой-либо SQL. Это может позволить вам зарегистрировать больше объектов для активности, а затем перезапустит план флеша, чтобы рассмотреть любые новые изменения (так как сейчас все работает). Как эта регистрация будет продолжаться, сложно, так как было бы неплохо использовать сессию, как правило, там, но это усложняет реализацию. Но затем он может снова именоваться в новых изменениях и найти все оставшиеся шаги, прежде чем продолжить.

Смежные вопросы