app/django/db/backends/sqlite3/base.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     4 Python 2.3 and 2.4 require pysqlite2 (http://pysqlite.org/).
     4 Python 2.3 and 2.4 require pysqlite2 (http://pysqlite.org/).
     5 
     5 
     6 Python 2.5 and later use the sqlite3 module in the standard library.
     6 Python 2.5 and later use the sqlite3 module in the standard library.
     7 """
     7 """
     8 
     8 
     9 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util
     9 from django.db.backends import *
       
    10 from django.db.backends.sqlite3.client import DatabaseClient
       
    11 from django.db.backends.sqlite3.creation import DatabaseCreation
       
    12 from django.db.backends.sqlite3.introspection import DatabaseIntrospection
       
    13 
    10 try:
    14 try:
    11     try:
    15     try:
    12         from sqlite3 import dbapi2 as Database
    16         from sqlite3 import dbapi2 as Database
    13     except ImportError:
    17     except ImportError, e1:
    14         from pysqlite2 import dbapi2 as Database
    18         from pysqlite2 import dbapi2 as Database
    15 except ImportError, e:
    19 except ImportError, exc:
    16     import sys
    20     import sys
    17     from django.core.exceptions import ImproperlyConfigured
    21     from django.core.exceptions import ImproperlyConfigured
    18     if sys.version_info < (2, 5, 0):
    22     if sys.version_info < (2, 5, 0):
    19         module = 'pysqlite2'
    23         module = 'pysqlite2'
    20     else:
    24     else:
    21         module = 'sqlite3'
    25         module = 'sqlite3'
    22     raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
    26         exc = e1
       
    27     raise ImproperlyConfigured, "Error loading %s module: %s" % (module, exc)
    23 
    28 
    24 try:
    29 try:
    25     import decimal
    30     import decimal
    26 except ImportError:
    31 except ImportError:
    27     from django.utils import _decimal as decimal # for Python 2.3
    32     from django.utils import _decimal as decimal # for Python 2.3
    35 Database.register_converter("datetime", util.typecast_timestamp)
    40 Database.register_converter("datetime", util.typecast_timestamp)
    36 Database.register_converter("timestamp", util.typecast_timestamp)
    41 Database.register_converter("timestamp", util.typecast_timestamp)
    37 Database.register_converter("TIMESTAMP", util.typecast_timestamp)
    42 Database.register_converter("TIMESTAMP", util.typecast_timestamp)
    38 Database.register_converter("decimal", util.typecast_decimal)
    43 Database.register_converter("decimal", util.typecast_decimal)
    39 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
    44 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
       
    45 if Database.version_info >= (2,4,1):
       
    46     # Starting in 2.4.1, the str type is not accepted anymore, therefore,
       
    47     # we convert all str objects to Unicode
       
    48     # As registering a adapter for a primitive type causes a small
       
    49     # slow-down, this adapter is only registered for sqlite3 versions
       
    50     # needing it.
       
    51     Database.register_adapter(str, lambda s:s.decode('utf-8'))
    40 
    52 
    41 class DatabaseFeatures(BaseDatabaseFeatures):
    53 class DatabaseFeatures(BaseDatabaseFeatures):
    42     supports_constraints = False
    54     # SQLite cannot handle us only partially reading from a cursor's result set
       
    55     # and then writing the same rows to the database in another cursor. This
       
    56     # setting ensures we always read result sets fully into memory all in one
       
    57     # go.
       
    58     can_use_chunked_reads = False
    43 
    59 
    44 class DatabaseOperations(BaseDatabaseOperations):
    60 class DatabaseOperations(BaseDatabaseOperations):
    45     def date_extract_sql(self, lookup_type, field_name):
    61     def date_extract_sql(self, lookup_type, field_name):
    46         # sqlite doesn't support extract, so we fake it with the user-defined
    62         # sqlite doesn't support extract, so we fake it with the user-defined
    47         # function django_extract that's registered in connect().
    63         # function django_extract that's registered in connect().
    77                  ) for table in tables]
    93                  ) for table in tables]
    78         # Note: No requirement for reset of auto-incremented indices (cf. other
    94         # Note: No requirement for reset of auto-incremented indices (cf. other
    79         # sql_flush() implementations). Just return SQL at this point
    95         # sql_flush() implementations). Just return SQL at this point
    80         return sql
    96         return sql
    81 
    97 
       
    98     def year_lookup_bounds(self, value):
       
    99         first = '%s-01-01'
       
   100         second = '%s-12-31 23:59:59.999999'
       
   101         return [first % value, second % value]
       
   102 
    82 class DatabaseWrapper(BaseDatabaseWrapper):
   103 class DatabaseWrapper(BaseDatabaseWrapper):
    83     features = DatabaseFeatures()
   104     
    84     ops = DatabaseOperations()
       
    85 
       
    86     # SQLite requires LIKE statements to include an ESCAPE clause if the value
   105     # SQLite requires LIKE statements to include an ESCAPE clause if the value
    87     # being escaped has a percent or underscore in it.
   106     # being escaped has a percent or underscore in it.
    88     # See http://www.sqlite.org/lang_expr.html for an explanation.
   107     # See http://www.sqlite.org/lang_expr.html for an explanation.
    89     operators = {
   108     operators = {
    90         'exact': '= %s',
   109         'exact': '= %s',
   101         'endswith': "LIKE %s ESCAPE '\\'",
   120         'endswith': "LIKE %s ESCAPE '\\'",
   102         'istartswith': "LIKE %s ESCAPE '\\'",
   121         'istartswith': "LIKE %s ESCAPE '\\'",
   103         'iendswith': "LIKE %s ESCAPE '\\'",
   122         'iendswith': "LIKE %s ESCAPE '\\'",
   104     }
   123     }
   105 
   124 
       
   125     def __init__(self, *args, **kwargs):
       
   126         super(DatabaseWrapper, self).__init__(*args, **kwargs)
       
   127         
       
   128         self.features = DatabaseFeatures()
       
   129         self.ops = DatabaseOperations()
       
   130         self.client = DatabaseClient()
       
   131         self.creation = DatabaseCreation(self)
       
   132         self.introspection = DatabaseIntrospection(self)
       
   133         self.validation = BaseDatabaseValidation()
       
   134 
   106     def _cursor(self, settings):
   135     def _cursor(self, settings):
   107         if self.connection is None:
   136         if self.connection is None:
       
   137             if not settings.DATABASE_NAME:
       
   138                 from django.core.exceptions import ImproperlyConfigured
       
   139                 raise ImproperlyConfigured, "Please fill out DATABASE_NAME in the settings module before using the database."
   108             kwargs = {
   140             kwargs = {
   109                 'database': settings.DATABASE_NAME,
   141                 'database': settings.DATABASE_NAME,
   110                 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
   142                 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
   111             }
   143             }
   112             kwargs.update(self.options)
   144             kwargs.update(self.options)
   149 def _sqlite_extract(lookup_type, dt):
   181 def _sqlite_extract(lookup_type, dt):
   150     try:
   182     try:
   151         dt = util.typecast_timestamp(dt)
   183         dt = util.typecast_timestamp(dt)
   152     except (ValueError, TypeError):
   184     except (ValueError, TypeError):
   153         return None
   185         return None
   154     return str(getattr(dt, lookup_type))
   186     return unicode(getattr(dt, lookup_type))
   155 
   187 
   156 def _sqlite_date_trunc(lookup_type, dt):
   188 def _sqlite_date_trunc(lookup_type, dt):
   157     try:
   189     try:
   158         dt = util.typecast_timestamp(dt)
   190         dt = util.typecast_timestamp(dt)
   159     except (ValueError, TypeError):
   191     except (ValueError, TypeError):