在Django中单个connection.cursor进行多次执行安全吗?

4 投票
1 回答
6296 浏览
提问于 2025-04-19 02:12

我正在用连接的游标(connection.cursor)来执行一系列的删除操作,然后再关闭这个游标。这个过程是可以正常工作的,但我不太确定这样做是否会有什么副作用。如果有人能给点反馈,我会很感激。

from django.db import connection
c=connection.cursor()
try:
    c.execute('delete from table_a')
    c.execute('delete from table_b')
    ...
finally:
    c.close()

1 个回答

5

因为你没有在事务中执行这些SQL语句,所以可能会遇到一些让人困惑的情况(比如,数据从table_a中删除了,但table_b中的数据却没有被删除)。

Django的文档对这种情况是这样说的:

如果你连续执行多个自定义的SQL查询,每个查询现在都在自己的事务中运行,而不是共享同一个“自动事务”。如果你需要确保操作的原子性(也就是要么全部成功,要么全部失败),你必须把这些查询放在atomic()中。

所以,每次调用execute()后,结果都会立即提交,但我们希望这些操作要么全部成功,要么全部失败——就像是一组整体的更改。

可以用transaction.atomic装饰器来包裹这个视图:

from django.db import transaction

@transaction.atomic
def my_view(request):
    c = connection.cursor()
    try:
        c.execute('delete from table_a')
        c.execute('delete from table_b')
    finally:
        c.close()

需要注意的是,atomic()和整个新事务管理系统是在Django 1.6中引入的。

如果你使用的是Django版本小于1.6的,应该使用transaction.commit_on_success装饰器。

撰写回答