Django1.6,将事务适用于原始SQL吗?

时间:2013-12-02 09:18:17

标签: python sql django django-models mysql-python

官方文件中的示例

from django.db import connection

def my_custom_sql(self):
    cursor = connection.cursor()

    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])

    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row

如果更新会影响选择,例如

cursor.execute("UPDATE bar SET foo = foo + 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])

事务是否适用于原始SQL,就像此快照代码一样有用吗?

from django.db import connection, transaction

def my_custom_sql(self):
    try:
        with transaction.atomic():
            cursor = connection.cursor()
            cursor.execute("UPDATE bar SET foo = foo + 1 WHERE baz = %s", [self.baz])
            cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
            row = cursor.fetchone()
            return row
    except IntegrityError:
        transaction.rollback()

或者对于第一个代码,开始游标已经启动了一个事务?

1 个答案:

答案 0 :(得分:1)

我只能看到self.db.validate_no_broken_transaction() here的健全性检查:

def execute(self, sql, params=None):
    self.db.validate_no_broken_transaction()
    self.db.set_dirty()
    with self.db.wrap_database_errors:
        if params is None:
            return self.cursor.execute(sql)
        else:
            return self.cursor.execute(sql, params)

所以答案是否定的,默认情况下,游标不会在事务中包装原始SQL。

<强>更新

如果您需要交易和ATOMIC_REQUESTS = False,则可以transaction.atomic()使用django.db.connection

NB: django.db.connections['default']仅适用于向后兼容性。你应该使用from django.db import DEFAULT_DB_ALIAS def get_connection(using=None): """ Get a database connection by name, or the default database connection if no name is provided. """ if using is None: using = DEFAULT_DB_ALIAS return connections[using] 甚至更好的

{{1}}

喜欢decorator or context manager