web/lib/django/db/backends/postgresql_psycopg2/base.py
author ymh <ymh.work@gmail.com>
Tue, 25 May 2010 02:43:45 +0200
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
permissions -rw-r--r--
update django and lucene
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
"""
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
PostgreSQL database backend for Django.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
Requires psycopg 2: http://initd.org/projects/psycopg2
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
"""
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     7
import sys
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     8
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     9
from django.db import utils
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
from django.db.backends import *
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
from django.db.backends.signals import connection_created
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
from django.db.backends.postgresql.operations import DatabaseOperations as PostgresqlDatabaseOperations
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
from django.db.backends.postgresql.client import DatabaseClient
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
from django.db.backends.postgresql.creation import DatabaseCreation
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
from django.db.backends.postgresql.version import get_version
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
from django.utils.safestring import SafeUnicode, SafeString
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
try:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    import psycopg2 as Database
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    import psycopg2.extensions
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
except ImportError, e:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    from django.core.exceptions import ImproperlyConfigured
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
DatabaseError = Database.DatabaseError
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
IntegrityError = Database.IntegrityError
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
psycopg2.extensions.register_adapter(SafeString, psycopg2.extensions.QuotedString)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
psycopg2.extensions.register_adapter(SafeUnicode, psycopg2.extensions.QuotedString)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    33
class CursorWrapper(object):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    34
    """
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    35
    A thin wrapper around psycopg2's normal cursor class so that we can catch
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    36
    particular exception instances and reraise them with the right types.
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    37
    """
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    38
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    39
    def __init__(self, cursor):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    40
        self.cursor = cursor
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    41
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    42
    def execute(self, query, args=None):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    43
        try:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    44
            return self.cursor.execute(query, args)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    45
        except Database.IntegrityError, e:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    46
            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    47
        except Database.DatabaseError, e:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    48
            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    49
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    50
    def executemany(self, query, args):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    51
        try:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    52
            return self.cursor.executemany(query, args)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    53
        except Database.IntegrityError, e:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    54
            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    55
        except Database.DatabaseError, e:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    56
            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    57
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    58
    def __getattr__(self, attr):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    59
        if attr in self.__dict__:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    60
            return self.__dict__[attr]
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    61
        else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    62
            return getattr(self.cursor, attr)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    63
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    64
    def __iter__(self):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    65
        return iter(self.cursor)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    66
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
class DatabaseFeatures(BaseDatabaseFeatures):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
    needs_datetime_string_cast = False
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
    can_return_id_from_insert = False
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
class DatabaseOperations(PostgresqlDatabaseOperations):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
    def last_executed_query(self, cursor, sql, params):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        # With psycopg2, cursor objects have a "query" attribute that is the
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        # exact query sent to the database. See docs here:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        # http://www.initd.org/tracker/psycopg/wiki/psycopg2_documentation#postgresql-status-message-and-executed-query
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        return cursor.query
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    def return_insert_id(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        return "RETURNING %s", ()
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
class DatabaseWrapper(BaseDatabaseWrapper):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
    operators = {
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
        'exact': '= %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
        'iexact': '= UPPER(%s)',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
        'contains': 'LIKE %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
        'icontains': 'LIKE UPPER(%s)',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
        'regex': '~ %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        'iregex': '~* %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
        'gt': '> %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
        'gte': '>= %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        'lt': '< %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
        'lte': '<= %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
        'startswith': 'LIKE %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        'endswith': 'LIKE %s',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
        'istartswith': 'LIKE UPPER(%s)',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        'iendswith': 'LIKE UPPER(%s)',
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
    }
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
    def __init__(self, *args, **kwargs):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        super(DatabaseWrapper, self).__init__(*args, **kwargs)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
        self.features = DatabaseFeatures()
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   103
        autocommit = self.settings_dict["OPTIONS"].get('autocommit', False)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        self.features.uses_autocommit = autocommit
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        self._set_isolation_level(int(not autocommit))
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   106
        self.ops = DatabaseOperations(self)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
        self.client = DatabaseClient(self)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        self.creation = DatabaseCreation(self)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        self.introspection = DatabaseIntrospection(self)
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   110
        self.validation = BaseDatabaseValidation(self)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
    def _cursor(self):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   113
        new_connection = False
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
        set_tz = False
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        settings_dict = self.settings_dict
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
        if self.connection is None:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   117
            new_connection = True
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   118
            set_tz = settings_dict.get('TIME_ZONE')
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   119
            if settings_dict['NAME'] == '':
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
                from django.core.exceptions import ImproperlyConfigured
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   121
                raise ImproperlyConfigured("You need to specify NAME in your Django settings file.")
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
            conn_params = {
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   123
                'database': settings_dict['NAME'],
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
            }
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   125
            conn_params.update(settings_dict['OPTIONS'])
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
            if 'autocommit' in conn_params:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
                del conn_params['autocommit']
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   128
            if settings_dict['USER']:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   129
                conn_params['user'] = settings_dict['USER']
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   130
            if settings_dict['PASSWORD']:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   131
                conn_params['password'] = settings_dict['PASSWORD']
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   132
            if settings_dict['HOST']:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   133
                conn_params['host'] = settings_dict['HOST']
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   134
            if settings_dict['PORT']:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   135
                conn_params['port'] = settings_dict['PORT']
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
            self.connection = Database.connect(**conn_params)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
            self.connection.set_client_encoding('UTF8')
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
            self.connection.set_isolation_level(self.isolation_level)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
            connection_created.send(sender=self.__class__)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
        cursor = self.connection.cursor()
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
        cursor.tzinfo_factory = None
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   142
        if new_connection:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   143
            if set_tz:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   144
                cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']])
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
            if not hasattr(self, '_version'):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
                self.__class__._version = get_version(cursor)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
            if self._version[0:2] < (8, 0):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
                # No savepoint support for earlier version of PostgreSQL.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
                self.features.uses_savepoints = False
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
            if self.features.uses_autocommit:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
                if self._version[0:2] < (8, 2):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
                    # FIXME: Needs extra code to do reliable model insert
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
                    # handling, so we forbid it for now.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
                    from django.core.exceptions import ImproperlyConfigured
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
                    raise ImproperlyConfigured("You cannot use autocommit=True with PostgreSQL prior to 8.2 at the moment.")
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
                else:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
                    # FIXME: Eventually we're enable this by default for
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
                    # versions that support it, but, right now, that's hard to
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
                    # do without breaking other things (#10509).
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
                    self.features.can_return_id_from_insert = True
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   161
        return CursorWrapper(cursor)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
    def _enter_transaction_management(self, managed):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
        Switch the isolation level when needing transaction support, so that
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
        the same transaction is visible across all the queries.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
        if self.features.uses_autocommit and managed and not self.isolation_level:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
            self._set_isolation_level(1)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
    def _leave_transaction_management(self, managed):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
        If the normal operating mode is "autocommit", switch back to that when
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
        leaving transaction management.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
        if self.features.uses_autocommit and not managed and self.isolation_level:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
            self._set_isolation_level(0)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
    def _set_isolation_level(self, level):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
        Do all the related feature configurations for changing isolation
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
        levels. This doesn't touch the uses_autocommit feature, since that
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        controls the movement *between* isolation levels.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
        """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
        assert level in (0, 1)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
        try:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
            if self.connection is not None:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
                self.connection.set_isolation_level(level)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
        finally:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
            self.isolation_level = level
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
            self.features.uses_savepoints = bool(level)