Подтвердить что ты не робот

SQLAlchemy delete не каскадирует

Моя модель User имеет отношение к модели Address. Я указал, что отношения должны каскадировать операцию удаления. Однако, когда я запрашиваю и удаляю пользователя, я получаю сообщение об ошибке, что строка адреса по-прежнему ссылается. Как удалить пользователя и адреса?

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    addresses = db.relationship('Address', cascade='all,delete', backref='user')

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey(User.id))
db.session.query(User).filter(User.my_id==1).delete()
IntegrityError: (IntegrityError) update or delete on table "user" violates foreign key constraint "addresses_user_id_fkey" on table "address"
DETAIL:  Key (my_id)=(1) is still referenced from table "address".
 'DELETE FROM "user" WHERE "user".id = %(id_1)s' {'id_1': 1}
4b9b3361

Ответ 1

У вас есть следующее...

db.session.query(User).filter(User.my_id==1).delete()

Обратите внимание, что после "фильтра" вы все равно возвращаете объект Query. Поэтому, когда вы вызываете delete(), вы вызываете delete() в объекте Query (а не в объекте User). Это означает, что вы делаете массовое удаление (хотя, вероятно, с удалением только одной строки)

Документация для используемого метода Query.delete() говорит...

Метод не предлагает каскадирование отношений в Python - это что ON DELETE CASCADE/SET NULL/etc. настраивается для любого ссылки на внешние ключи, которые требуют этого, в противном случае база данных может испускать нарушение целостности, если ссылки на внешние ключи в жизнь.

Как говорится, при запуске delete таким образом игнорируются установленные вами каскадные правила Python. Вы, наверное, хотели сделать что-то вроде..

user = db.session.query(User).filter(User.my_id==1).first()
db.session.delete(user)

В противном случае вы можете посмотреть настройку каскада для своей базы данных, а также.