Skip to content

Instantly share code, notes, and snippets.

@rctay
Created July 4, 2012 08:09
Show Gist options
  • Save rctay/3046025 to your computer and use it in GitHub Desktop.
Save rctay/3046025 to your computer and use it in GitHub Desktop.
[django] backport savepoints for MySQL
from django.db.backends import BaseDatabaseFeatures
from django.db.backends.mysql.base import (
DatabaseFeatures as MySQLDatabaseFeatures,
DatabaseOperations as MySQLDatabaseOperations,
)
try:
from django.util.functional import cached_property
except ImportError:
# Backport from django 1.4
class cached_property(object):
"""
Decorator that creates converts a method with a single
self argument into a property cached on the instance.
"""
def __init__(self, func):
self.func = func
def __get__(self, instance, type):
res = instance.__dict__[self.func.__name__] = self.func(instance)
return res
class Features(object):
# Backport from django 1.4
@cached_property
def _mysql_storage_engine(self):
"Internal method used in Django tests. Don't rely on this from your code"
cursor = self.connection.cursor()
cursor.execute('CREATE TABLE INTROSPECT_TEST (X INT)')
# This command is MySQL specific; the second column
# will tell you the default table type of the created
# table. Since all Django's test tables will have the same
# table type, that's enough to evaluate the feature.
cursor.execute("SHOW TABLE STATUS WHERE Name='INTROSPECT_TEST'")
result = cursor.fetchone()
cursor.execute('DROP TABLE INTROSPECT_TEST')
return result[1]
# Backport from django 1.4 + fix to check for InnoDB
@property
def uses_savepoints(self):
return self._mysql_storage_engine == 'InnoDB' or \
self.get_server_version() >= (5, 0, 3)
# django 1.4 will set this property, so stub it
@uses_savepoints.setter
def uses_savepoints(self, value):
pass
if Features not in MySQLDatabaseFeatures.__bases__:
MySQLDatabaseFeatures.__bases__ = (Features, ) + MySQLDatabaseFeatures.__bases__
# Backport from django 1.4
class Operations(object):
def savepoint_create_sql(self, sid):
return "SAVEPOINT %s" % sid
def savepoint_commit_sql(self, sid):
return "RELEASE SAVEPOINT %s" % sid
def savepoint_rollback_sql(self, sid):
return "ROLLBACK TO SAVEPOINT %s" % sid
if Operations not in MySQLDatabaseOperations.__bases__:
MySQLDatabaseOperations.__bases__ = (Operations, ) + MySQLDatabaseOperations.__bases__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment