我的 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 中的错误。
最佳答案
长话短说 您的问题可能与缺少明确的关系声明有关。
例如,here有一个对象关系的样本。除了使用 ForeignKey 字段外,该类还明确使用 relationship
指令来定义该连接。在session API documentation ,出现以下文本:
object references should be constructed at the object level, not at the foreign key level
这可能暗示了 SQLAlchemy 管理关系的方式。我对底层机制不是很熟悉,但这可能就是发生的事情。您的 session 仅包含 MyModelA
对象。由于您没有在 MyModelB
的定义中使用 relationship()
指令,因此 MyModelA
类型的对象不知道其他一些对象可能通过 ForeignKey
引用它们。因此,当 session 即将提交时,它不知道删除该对象会影响其他一些 MyModelB
对象这一事实,并且它的事务机制没有考虑到这一点。
我建议明确添加关系可能会阻止这种行为。
关于python - 数据库异常后 SQLAlchemy 回滚中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40681371/