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): |