Examples from offical document
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
if update will affect select, for example
cursor.execute("UPDATE bar SET foo = foo + 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
Does transaction works for raw SQL, like this snap code works?
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()
Or the for the first code, begin cursor already start a transaction?
I can see only sanity checks with 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)
So the answer is no, cursor doesn't wrap raw SQL in transaction by default.
Update:
If you need transactions and ATOMIC_REQUESTS = False
you can use transaction.atomic()
like decorator or context manager.
NB: django.db.connection
is there only for backwards comnatibility. You should use django.db.connections['default']
or even better
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]
like here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With