app/django/db/backends/postgresql/base.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     2 PostgreSQL database backend for Django.
     2 PostgreSQL database backend for Django.
     3 
     3 
     4 Requires psycopg 1: http://initd.org/projects/psycopg1
     4 Requires psycopg 1: http://initd.org/projects/psycopg1
     5 """
     5 """
     6 
     6 
       
     7 from django.db.backends import *
       
     8 from django.db.backends.postgresql.client import DatabaseClient
       
     9 from django.db.backends.postgresql.creation import DatabaseCreation
       
    10 from django.db.backends.postgresql.introspection import DatabaseIntrospection
       
    11 from django.db.backends.postgresql.operations import DatabaseOperations
       
    12 from django.db.backends.postgresql.version import get_version
     7 from django.utils.encoding import smart_str, smart_unicode
    13 from django.utils.encoding import smart_str, smart_unicode
     8 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, util
    14 
     9 from django.db.backends.postgresql.operations import DatabaseOperations
       
    10 try:
    15 try:
    11     import psycopg as Database
    16     import psycopg as Database
    12 except ImportError, e:
    17 except ImportError, e:
    13     from django.core.exceptions import ImproperlyConfigured
    18     from django.core.exceptions import ImproperlyConfigured
    14     raise ImproperlyConfigured("Error loading psycopg module: %s" % e)
    19     raise ImproperlyConfigured("Error loading psycopg module: %s" % e)
    58 
    63 
    59     def __iter__(self):
    64     def __iter__(self):
    60         return iter(self.cursor)
    65         return iter(self.cursor)
    61 
    66 
    62 class DatabaseFeatures(BaseDatabaseFeatures):
    67 class DatabaseFeatures(BaseDatabaseFeatures):
    63     pass # This backend uses all the defaults.
    68     uses_savepoints = True
    64 
    69 
    65 class DatabaseWrapper(BaseDatabaseWrapper):
    70 class DatabaseWrapper(BaseDatabaseWrapper):
    66     features = DatabaseFeatures()
       
    67     ops = DatabaseOperations()
       
    68     operators = {
    71     operators = {
    69         'exact': '= %s',
    72         'exact': '= %s',
    70         'iexact': 'ILIKE %s',
    73         'iexact': '= UPPER(%s)',
    71         'contains': 'LIKE %s',
    74         'contains': 'LIKE %s',
    72         'icontains': 'ILIKE %s',
    75         'icontains': 'LIKE UPPER(%s)',
    73         'regex': '~ %s',
    76         'regex': '~ %s',
    74         'iregex': '~* %s',
    77         'iregex': '~* %s',
    75         'gt': '> %s',
    78         'gt': '> %s',
    76         'gte': '>= %s',
    79         'gte': '>= %s',
    77         'lt': '< %s',
    80         'lt': '< %s',
    78         'lte': '<= %s',
    81         'lte': '<= %s',
    79         'startswith': 'LIKE %s',
    82         'startswith': 'LIKE %s',
    80         'endswith': 'LIKE %s',
    83         'endswith': 'LIKE %s',
    81         'istartswith': 'ILIKE %s',
    84         'istartswith': 'LIKE UPPER(%s)',
    82         'iendswith': 'ILIKE %s',
    85         'iendswith': 'LIKE UPPER(%s)',
    83     }
    86     }
       
    87 
       
    88     def __init__(self, *args, **kwargs):
       
    89         super(DatabaseWrapper, self).__init__(*args, **kwargs)
       
    90 
       
    91         self.features = DatabaseFeatures()
       
    92         self.ops = DatabaseOperations()
       
    93         self.client = DatabaseClient()
       
    94         self.creation = DatabaseCreation(self)
       
    95         self.introspection = DatabaseIntrospection(self)
       
    96         self.validation = BaseDatabaseValidation()
    84 
    97 
    85     def _cursor(self, settings):
    98     def _cursor(self, settings):
    86         set_tz = False
    99         set_tz = False
    87         if self.connection is None:
   100         if self.connection is None:
    88             set_tz = True
   101             set_tz = True
   101             self.connection = Database.connect(conn_string, **self.options)
   114             self.connection = Database.connect(conn_string, **self.options)
   102             self.connection.set_isolation_level(1) # make transactions transparent to all cursors
   115             self.connection.set_isolation_level(1) # make transactions transparent to all cursors
   103         cursor = self.connection.cursor()
   116         cursor = self.connection.cursor()
   104         if set_tz:
   117         if set_tz:
   105             cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
   118             cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
       
   119             if not hasattr(self, '_version'):
       
   120                 self.__class__._version = get_version(cursor)
       
   121             if self._version < (8, 0):
       
   122                 # No savepoint support for earlier version of PostgreSQL.
       
   123                 self.features.uses_savepoints = False
   106         cursor.execute("SET client_encoding to 'UNICODE'")
   124         cursor.execute("SET client_encoding to 'UNICODE'")
   107         cursor = UnicodeCursorWrapper(cursor, 'utf-8')
   125         cursor = UnicodeCursorWrapper(cursor, 'utf-8')
   108         return cursor
   126         return cursor
   109 
   127 
   110 def typecast_string(s):
   128 def typecast_string(s):