19 июн. 2008 г.

Борьба с обNULLением в SQLAlchemy

SQLAlchemy, пожалуй, самый продвинутый ORM для питона. Но, к сожалению, он постоянно подбрасывает неприятные сюрпризы. В очередной раз натолкнувшись на одну из проблем и потратив время на повторный поиск её решения, я решил его задокументировать. Речь об установки в NULL поля с идентификатором при удалении объекта, на который он ссылается, если в маппере для связи используется relation. Для тех, кто привык работать с SQL, такое поведение по умолчанию в лучшем случае вызывает недоумение. Фактически оно означает использование на уровне кода по умолчанию правила ON DELETE SET NULL, вместо привычного (и логичного!) ON DELETE RESTRICT. Если бы не моя чрезмерная педантичность в проставлении nullable=False для полей с FOREIGN KEY, этот сюрприз мог бы привести к весьма печальным последствиям - потери данных. Упоминание об описанном поведении в документации к SQLAlchemy встречается только один раз - при описании ключа passive_deletes функции relation(). Собственно его установка в 'all' и решает проблему. Так как имя ключа ничего не говорит о его истинном назначении, то соответствующий комментарий явно не помешает.

3 комментария:

Marten комментирует...

Вот спасибо! Казалось бы, очевидная вещь и должна быть описана, ан нет...

Unknown комментирует...

Ну в последних версиях, насколько я помню, этой проблемы уже нет. Так что этот пост имеет лишь историческую ценность.

Marten комментирует...

Для версии 0.7 stable оказалось актуально