无效请求错误:实例 '<User at 0x7f65938a7510>' 未被持久化

14 投票
3 回答
37382 浏览
提问于 2025-04-30 00:47

我想在Flask这个框架中进行这样的测试,并且收到了这个消息:

InvalidRequestError: Instance '<User at 0x7f65938a7510>' is not persisted

  File "tests.py", line 31, in test_removeProfil
    db.session.delete(user)

我的测试代码是:

class TestCase(unittest.TestCase):

    def test_removeProfil(self):
        user = User(name="John", age=33, email="john@john.com")
        db.session.delete(user)
        db.session.commit()
        self.assertNotEqual(user.name, "John")
        self.assertNotEqual(user.age, 33)
        self.assertNotEqual(user.email, "john@john.com")
暂无标签

3 个回答

0

如果你把一个对象添加到会话中,但这个对象已经在数据库里了,就会出现错误。这时候,你可以使用session.rollback()这个命令来帮助你。

session.add(obj)

try:
    if commit:
        session.commit()
except:
    session.rollback()
8

当你调用

user = User(name="John", age=33, email="john@john.com")

时,你创建的是一个Python对象,而不是数据库里的对象。所以你需要先把它添加到数据库里

db.session.add(user)
db.session.commit()

之后你才能从数据库中删除它

db.session.delete(user)
db.session.commit()

而你的 assertNotEqual 就没有意义了。你应该测试从数据库中选择的结果,在删除之前和之后是否不同

18

你现在试图删除一个新创建的实例,而不是从数据库中获取的实例。你可能是想用 db.session.add() 来添加一个新的实例,或者你应该用 user = User.query.filter_by(email='john@john.com').first()(或者类似的方式)来获取那个实例,然后再删除它。

如果你正确地删除了实例,你可能还会遇到访问已删除实例属性的问题。当你提交一个会话时,所有在这个会话中的实例都会失效。试图访问一个失效的属性会触发数据库查找,但这个对象已经被删除,所以无法进行查找。

你可以关闭 expire_on_commit,但这不是正常的做法,可能会导致其他问题。

你也可以尝试对它调用 make_transient

总的来说,你应该放弃那些已经被删除的实例。可能有更好的方法来完成你想做的事情。

撰写回答