Каков хороший подход для проверки существования уникальных значений в таблице базы данных с помощью SqlAlchemy в python2.7?
Я использую session.merge
в SqlAlchemy, чтобы вставить данные в таблицу с UniqueConstraint
, что является общим для нескольких столбцов, например, мой класс ORM имеет следующее:
UniqueConstraint("attr_1", "attr_2", "attr_3", name="attributes_uix")
Должен ли я использовать filter
или же filter_by
с _and
чтобы проверить, будут ли данные, которые я собираюсь вставить, нарушать это уникальное ограничение, или это правильный способ поймать IntegrityError
от try - except
строительство?
1 ответ
Нет эксперта по sql-alchemy, но некоторое время боролся с этим и схожими вопросами. Я не уверен, есть ли единственно правильный путь в этом случае. То, что я могу описать для вас, - это каков компромисс между захватом исключений из БД и обработкой его в вашем коде.
Лично я предпочитаю ловить исключения БД. Преимущество в том, что дополнительные запросы не выполняются (с дополнительной задержкой и т. Д.). Это также имеет преимущество повторного использования существующих частей фреймворка в максимально возможной степени.
Однако у него есть два реальных недостатка. Первое, которое может быть решено на уровне проектирования БД, состоит в том, что уникальные ограничения для нескольких столбцов не нарушаются совпадениями, содержащими значения NULL. Другими словами, если у меня есть ограничение (id, значение), то (1, null), (1, null)
нельзя сказать, что она не уникальна, и поэтому исключение целостности не выдается. Поэтому сначала стоит проверить, можете ли вы избежать этой проблемы. Если нет, вам нужно найти обходной путь, но PostgreSQL предоставляет вам множество инструментов (например, функциональные индексы).
Во-вторых, перехват IntegrityError является своего рода тупым инструментом, и вы не можете реально проанализировать любое сообщение об ошибке, доступное для имени индекса, потому что это может варьироваться в зависимости от системы, и локаль может означать, что сообщение может быть переведено. Итак, вы полагаетесь на SQLSTATE, и это не очень точно. Т.е. у вас нет хорошей машиночитаемой информации. о том, какое ограничение было нарушено, если есть несколько кандидатов.
Тогда возникает вопрос о дублировании кода и запросов. Обычно я думаю, что поймать ошибку - меньшее зло, но из-за компромиссов это не универсальная рекомендация.