我在SQLAlchemy中删除模型实例时遇到问题。我最近添加了一个额外的表,这个添加引入了这个问题。我添加的表名为editrecords
。
数据库是带有InnoDB引擎的MySQL。
模型定义如下:
from sqlalchemy.ext.declarative import declarative_base
Model = declarative_base(name='Model')
class HasId(object):
@declared_attr
def id(cls):
return Column('id', Integer, Sequence('test_id_seq'), primary_key=True)
...
class TestParent(HasId, Model):
__tablename__ = 'tests'
discriminator = Column(String(50))
__mapper_args__ = {'polymorphic_on': discriminator}
...
class FooTest(TestParent):
__tablename__ = 'footests'
__mapper_args__ = {'polymorphic_identity': 'footests'}
id = Column(Integer, ForeignKey('tests.id', ondelete='CASCADE'), primary_key=True)
...
class EditRecord(Model):
__tablename__ = 'editrecords'
id = Column(Integer, Sequence('editrecord_id_seq'), primary_key=True)
test_id = Column(Integer, ForeignKey('tests.id', ondelete='CASCADE'), nullable=False)
...
这是删除发生的功能
def delete_test(test_id):
test = TestParent.query.get(test_id)
db_session.delete(test)
db_session.commit()
return( jsonify( {'deleted_test': test_id} ) )
我尝试修改模型上的ForeignKey
属性ondelete='CASCADE'
并重建数据库,尽管似乎没有任何工作。我尝试删除测试时,editrecords
表格给了我一些问题,因为它有ForeignKey
指向tests
。
我收到的错误消息如下(当我尝试在delete_test
中提交交易时触发)
IntegrityError: (pymysql.err.IntegrityError) (1452, u'Cannot add or update a child row: a foreign key constraint fails (`bayswater_DEV`.`editrecords`, CONSTRAINT `editrecords_ibfk_1` FOREIGN KEY (`test_id`) REFERENCES `tests` (`id`) ON DELETE CASCADE)') [SQL: u'UPDATE editrecords SET test_id=%s WHERE editrecords.id = %s'] [parameters: (None, 2)]
编辑:上表SHOW CREATE TABLE <table>
的结果
测试:http://pastebin.com/uFcEMzVZ
footests:http://pastebin.com/62uhECYn
editrecords:http://pastebin.com/3LekPywN
答案 0 :(得分:0)
问题是你有两个来自foo测试和editrecord表的外键到测试表
footests
CONSTRAINT `footests_ibfk_1` FOREIGN KEY (`id`) REFERENCES `tests` (`id`) ON DELETE CASCADE,
CONSTRAINT `footests_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `footests` (`id`) ON DELETE CASCADE;
edotrecords
CONSTRAINT `editrecords_ibfk_1` FOREIGN KEY (`test_id`) REFERENCES `tests` (`id`) ON DELETE CASCADE,
CONSTRAINT `editrecords_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);
在这种情况下你不能删除级联 因为我们假设您从 editrecord 删除记录 它将尝试从测试表中删除相关记录(在删除级联上) 但是那些测试ID也在 footest 表中用作外键 由于foregin键约束,它不会从测试表中删除那些记录,因此你的delete语句将失败
同样的事情发生,如果你要从foo测试删除它有删除级联外键,它会尝试从测试中删除记录,但他们已经在editrecord中使用外键,所以它不会删除
这将是一个看不见的情况,你不能同时从两个表中删除记录。所以请问题是ON删除级联并从表级别删除它并从代码级别处理它
使用此表设计,您无法从footest或editrecord表中删除条目