Как установить ограничения... отложенные в SQLALchemy CorePython

Программы на Python
Ответить
Anonymous
 Как установить ограничения... отложенные в SQLALchemy Core

Сообщение Anonymous »

Я использую SQLAlchemy и PostgreSQL. Postgres поддерживает выполнение отложенных ограничений, что позволяет нам отложить проверку ограничений таблицы до конца транзакции.

Например, в SQLAlchemy я мог бы определить таблицу следующим образом:

Код: Выделить всё

t_group_categories = Table('group_categories', metadata,
Column('id', Integer, primary_key=True),
Column('group_id', Integer, ForeignKey('groups.id', deferrable=True))
)
SQLAlchemy сгенерирует оператор CREATE TABLE, который будет выглядеть примерно так:

Код: Выделить всё

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
)
Насколько я понимаю, DEFERRABLE INITIALLY IMMEDIATE означает, что ограничение FOREIGN KEY
будет действовать так, как будто это ограничение без отсрочки, если только явно не указано
иначе, а это именно то, что я хочу.

Проблема в том, что я не могу найти никакой информации о том, как получить Ядро 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") внутри блока транзакции также возвращает Ошибка целостности.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»