我的SQLAlchemy应用程序(在MariaDB之上运行)包括两个模型MyModelA
和MyModelB
,其中后者是前者的子记录:
class MyModelA(db.Model):
a_id = db.Column(db.Integer, nullable=False, primary_key=True)
my_field1 = db.Column(db.String(1024), nullable=True)
class MyModelB(db.Model):
b_id = db.Column(db.Integer, nullable=False, primary_key=True)
a_id = db.Column(db.Integer, db.ForeignKey(MyModelA.a_id), nullable=False)
my_field2 = db.Column(db.String(1024), nullable=True)
这些是我创建的MyModelA
和MyModelB
的实例:
>>> my_a = MyModelA(my_field1="A1")
>>> my_a.aid
1
>>> MyModelB(a_id=my_a.aid, my_field2="B1")
我有以下代码删除MyModelA
a_id==1
的实例:
db.session.commit()
try:
my_a = MyModelA.query.get(a_id=1)
assert my_a is not None
print "#1) Number of MyModelAs: %s\n" % MyModelA.query.count()
db.session.delete(my_a)
db.session.commit()
except IntegrityError:
print "#2) Cannot delete instance of MyModelA because it has child record(s)!"
db.session.rollback()
print "#3) Number of MyModelAs: %s\n" % MyModelA.query.count()
当我运行此代码时,请查看我得到的意外结果:
#1) Number of MyModelAs: 1
#2) Cannot delete instance of MyModelA because it has child record(s)!
#3) Number of MyModelAs: 0
删除假定失败,数据库抛出异常导致回滚。但是,即使在回滚之后,表中的行数也表明该行 - 据说没有被删除 - 实际上已经消失了!
为什么会这样?我怎样才能解决这个问题?这似乎是SQLAlchemy中的一个错误。
答案 0 :(得分:0)
<强> TL; DR 强> 您的问题可能与缺乏明确的关系声明有关。
例如,here有一个对象样本&#39;关系。除了使用ForeignKey字段外,该类还显式使用relationship
指令来定义该连接。在session API documentation中,会显示以下文字:
对象引用应该在对象级别构建,而不是在外键级别构建
这可能意味着SQLAlchemy管理关系的方式。我对底层机制并不十分熟悉,但有可能发生这种情况。您的会话仅包含MyModelA
对象。由于您未在relationship()
的定义中使用MyModelB
指令,因此MyModelA
类型的对象不了解某些其他对象可能通过ForeignKey
引用它们的事实。因此,当会话即将提交时,它不知道删除该对象会影响某些其他MyModelB
对象,并且其事务机制不会考虑这一点。
我建议明确添加关系可能会阻止这种行为。