SQLAlchemy принципиально не нужно ничего знать об ограничениях вашей базы данных.Если в вашей базе данных есть ограничения, которые вы хотите сконфигурировать, вы, по сути, сделали это - ваша база данных запрещает делать то, что она не должна делать.
Ключевой темой SQLAlchemy является то, что она действительно выполняет только то, чтоВы говорите это.Поэтому, если вы попытаетесь сохранить объект SubWidget (), который в базе данных должен иметь ссылку на родительский Widget (), в тот момент, когда SQLAlchemy сбрасывает данные (т. Е. Выдает операторы INSERT), операция завершится неудачно.с нарушением ограничения, генерируемым базой данных, и транзакция откатывается.
Таким образом, предполагая, что FK для "subwidget" ссылается на "widget", ваше приложение должно убедиться, что данные находятся в правильной структуре.Есть два способа сделать это;один из них заключается в том, что вы вручную поддерживаете те столбцы, которые содержат ссылки на внешние ключи, и гарантируете, что они имеют соответствующее значение в точке INSERT или UPDATE.Другой способ заключается в том, что вы будете использовать relationship()
для управления атрибутом внешнего ключа и вместо этого обеспечите, чтобы создание объекта SubWidget () сопровождалось операцией связывания его с родительским объектом Widget (), который выВы создали и / или приобрели отдельно.
Что касается каскадов, то отличная идея, хотя и не обязательная, иметь ON DELETE CASCADE для тех внешних ключей, где это применимо.Что касается SQLAlchemy, то при использовании relationship()
вы обычно хотите дать ORM подсказку, что база данных будет каскадно удаляться через флаг passive_deletes (http://www.sqlalchemy.org/docs/orm/collections.html?highlight=passive_deletes#using-passive-deletes), однако обычно это повышение производительности;В противном случае SQLAlchemy гарантирует, что все объекты, представленные на зависимой стороне relationship()
, загружаются в память и обрабатываются соответствующим образом, что означает либо установку атрибута внешнего ключа на NULL (по умолчанию), либо маркировку зависимого объекта для удаления (это происходит путем установки "cascade" в значение "all, delete-orphan", см. http://www.sqlalchemy.org/docs/orm/session.html#cascades).
ON UPDATE Каскад менее распространен, так как естественные первичные ключи не являются обычной практикой в наши дни, так как они на самом деле неработают так же, как простые целочисленные первичные ключи, а также могут быть громоздкими другими способами. Однако SQLAlchemy также поддерживает их, и они, как правило, позаботятся о себе, так как SQLA предполагает, что по умолчанию каскады обновлений имеют место, когда происходит мутация PKсм. http://www.sqlalchemy.org/docs/orm/relationships.html#mutable-primary-keys-update-cascades для подробного описания этого.
Возможно, это все проще, если немного поэкспериментировать, основная идея в том, что SQLAlchemy испускает только тот SQL, о котором вы говоритехотя многие из его поведения SQLrs автоматизированы после предварительной настройки.relationship()
должен быть настроен с подробной информацией о том, как вы хотите, чтобы он вел себя, когда данные сохраняются, изменяются или удаляются с учетом ограничений, присутствующих в базе данных.