Например, в SQLAlchemy я мог бы определить таблицу следующим образом:
Код: Выделить всё
t_group_categories = Table('group_categories', metadata,
Column('id', Integer, primary_key=True),
Column('group_id', Integer, ForeignKey('groups.id', deferrable=True))
)
Код: Выделить всё
CREATE TABLE group_categories
(
id serial NOT NULL,
group_id integer,
CONSTRAINT group_categories_pkey PRIMARY KEY (id),
CONSTRAINT group_categories_group_id_fkey FOREIGN KEY (group_id)
REFERENCES groups (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE
)
будет действовать так, как будто это ограничение без отсрочки, если только явно не указано
иначе, а это именно то, что я хочу.
Проблема в том, что я не могу найти никакой информации о том, как получить Ядро SQLAlchemy фактически выдает команду SET CONSTRAINTS ... DEFERRED внутри транзакции.
Например, предположим, что у меня есть следующий код:
Код: Выделить всё
connection = engine.connect()
...
with connection.begin() as transaction:
# Create a group
r = connection.execute(
t_groups.insert().values(...)
)
group_id = r.inserted_primary_key
# Assign a category to the group (ERROR!)
r2 = connection.execute(
t_group_categories.insert().values(group_id=group_id, ...)
)
мы только что создали, категорию. Проблема в том, что без специального SET CONSTRAINTS ... DEFERRED
мы не можем фактически создать запись group_categories без нарушения ограничений внешнего ключа
таблицы, поскольку транзакция еще не зафиксирована.
В этом случае я хочу отложить проверку ограничения до момента фиксации транзакции.
Как я могу на самом деле отложить проверку ограничений до завершения транзакции?
Примечания:
- Вопрос в
Как установить ОТЛОЖЕННЫЕ ОГРАНИЧЕНИЯ в язык выражений sqlalchemy? аналогично, но ОП был заинтересован в использовании DEFERRABLE INITIALLY DEFERRED, чего я бы предпочел не делать. Вместо этого (если возможно) я хочу сохранить мое ограничение как DEFERRABLE INITIALLY IMMEDIATE и явно отмечать случаи, когда ограничение необходимо отложить. - SQLAlchemy — это тот, который сгенерировал ограничение DEFERRABLE INITIALLY DEFERRED, поэтому я надеюсь/предполагаю, что у него есть выразительный способ фактического использования этого ограничения на другой стороне (а именно, способ языка выражений для выдачи SET CONSTRAINTS ... DEFERRED.
Обновление:
- Выполнение Connection.execute("SET CONSTRAINTS ALL DEFERRED") также не имеет никакого эффекта; я все еще получаю ошибку IntegrityError.
- Выполнение Connection.execute("SET CONSTRAINTS group_categories_group_id_fkey DEFERRED") внутри блока транзакции также возвращает Ошибка целостности.
Мобильная версия