【问题标题】:Django1.6, will transaction works for raw SQL?Django1.6,事务是否适用于原始 SQL?
【发布时间】:2013-12-17 22:42:54
【问题描述】:

来自官方文档的示例

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,就像这个 snap 代码一样有效?

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()

或者对于第一个代码,begin cursor已经开始一个事务?

【问题讨论】:

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


    【解决方案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(),如decorator or context manager

    注意: django.db.connection 仅用于向后通信。你应该使用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]
    

    点赞here

    【讨论】:

    • 所以我应该添加 transaction.atomic?
    • 哦,对不起。我的错。是的,使用 transaction.atomic() 就像上下文管理器一样。我已经更新了答案
    猜你喜欢
    • 2021-02-19
    • 2017-07-18
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    相关资源
    最近更新 更多