22 raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__) |
23 raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__) |
23 |
24 |
24 from MySQLdb.converters import conversions |
25 from MySQLdb.converters import conversions |
25 from MySQLdb.constants import FIELD_TYPE, FLAG, CLIENT |
26 from MySQLdb.constants import FIELD_TYPE, FLAG, CLIENT |
26 |
27 |
|
28 from django.db import utils |
27 from django.db.backends import * |
29 from django.db.backends import * |
28 from django.db.backends.signals import connection_created |
30 from django.db.backends.signals import connection_created |
29 from django.db.backends.mysql.client import DatabaseClient |
31 from django.db.backends.mysql.client import DatabaseClient |
30 from django.db.backends.mysql.creation import DatabaseCreation |
32 from django.db.backends.mysql.creation import DatabaseCreation |
31 from django.db.backends.mysql.introspection import DatabaseIntrospection |
33 from django.db.backends.mysql.introspection import DatabaseIntrospection |
80 self.cursor = cursor |
82 self.cursor = cursor |
81 |
83 |
82 def execute(self, query, args=None): |
84 def execute(self, query, args=None): |
83 try: |
85 try: |
84 return self.cursor.execute(query, args) |
86 return self.cursor.execute(query, args) |
|
87 except Database.IntegrityError, e: |
|
88 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2] |
85 except Database.OperationalError, e: |
89 except Database.OperationalError, e: |
86 # Map some error codes to IntegrityError, since they seem to be |
90 # Map some error codes to IntegrityError, since they seem to be |
87 # misclassified and Django would prefer the more logical place. |
91 # misclassified and Django would prefer the more logical place. |
88 if e[0] in self.codes_for_integrityerror: |
92 if e[0] in self.codes_for_integrityerror: |
89 raise Database.IntegrityError(tuple(e)) |
93 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2] |
90 raise |
94 raise |
|
95 except Database.DatabaseError, e: |
|
96 raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2] |
91 |
97 |
92 def executemany(self, query, args): |
98 def executemany(self, query, args): |
93 try: |
99 try: |
94 return self.cursor.executemany(query, args) |
100 return self.cursor.executemany(query, args) |
|
101 except Database.IntegrityError, e: |
|
102 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2] |
95 except Database.OperationalError, e: |
103 except Database.OperationalError, e: |
96 # Map some error codes to IntegrityError, since they seem to be |
104 # Map some error codes to IntegrityError, since they seem to be |
97 # misclassified and Django would prefer the more logical place. |
105 # misclassified and Django would prefer the more logical place. |
98 if e[0] in self.codes_for_integrityerror: |
106 if e[0] in self.codes_for_integrityerror: |
99 raise Database.IntegrityError(tuple(e)) |
107 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2] |
100 raise |
108 raise |
|
109 except Database.DatabaseError, e: |
|
110 raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2] |
101 |
111 |
102 def __getattr__(self, attr): |
112 def __getattr__(self, attr): |
103 if attr in self.__dict__: |
113 if attr in self.__dict__: |
104 return self.__dict__[attr] |
114 return self.__dict__[attr] |
105 else: |
115 else: |
111 class DatabaseFeatures(BaseDatabaseFeatures): |
121 class DatabaseFeatures(BaseDatabaseFeatures): |
112 empty_fetchmany_value = () |
122 empty_fetchmany_value = () |
113 update_can_self_select = False |
123 update_can_self_select = False |
114 allows_group_by_pk = True |
124 allows_group_by_pk = True |
115 related_fields_match_type = True |
125 related_fields_match_type = True |
|
126 allow_sliced_subqueries = False |
116 |
127 |
117 class DatabaseOperations(BaseDatabaseOperations): |
128 class DatabaseOperations(BaseDatabaseOperations): |
|
129 compiler_module = "django.db.backends.mysql.compiler" |
|
130 |
118 def date_extract_sql(self, lookup_type, field_name): |
131 def date_extract_sql(self, lookup_type, field_name): |
119 # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html |
132 # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html |
120 if lookup_type == 'week_day': |
133 if lookup_type == 'week_day': |
121 # DAYOFWEEK() returns an integer, 1-7, Sunday=1. |
134 # DAYOFWEEK() returns an integer, 1-7, Sunday=1. |
122 # Note: WEEKDAY() returns 0-6, Monday=0. |
135 # Note: WEEKDAY() returns 0-6, Monday=0. |
211 def year_lookup_bounds(self, value): |
224 def year_lookup_bounds(self, value): |
212 # Again, no microseconds |
225 # Again, no microseconds |
213 first = '%s-01-01 00:00:00' |
226 first = '%s-01-01 00:00:00' |
214 second = '%s-12-31 23:59:59.99' |
227 second = '%s-12-31 23:59:59.99' |
215 return [first % value, second % value] |
228 return [first % value, second % value] |
|
229 |
|
230 def max_name_length(self): |
|
231 return 64 |
216 |
232 |
217 class DatabaseWrapper(BaseDatabaseWrapper): |
233 class DatabaseWrapper(BaseDatabaseWrapper): |
218 |
234 |
219 operators = { |
235 operators = { |
220 'exact': '= %s', |
236 'exact': '= %s', |
240 self.features = DatabaseFeatures() |
256 self.features = DatabaseFeatures() |
241 self.ops = DatabaseOperations() |
257 self.ops = DatabaseOperations() |
242 self.client = DatabaseClient(self) |
258 self.client = DatabaseClient(self) |
243 self.creation = DatabaseCreation(self) |
259 self.creation = DatabaseCreation(self) |
244 self.introspection = DatabaseIntrospection(self) |
260 self.introspection = DatabaseIntrospection(self) |
245 self.validation = DatabaseValidation() |
261 self.validation = DatabaseValidation(self) |
246 |
262 |
247 def _valid_connection(self): |
263 def _valid_connection(self): |
248 if self.connection is not None: |
264 if self.connection is not None: |
249 try: |
265 try: |
250 self.connection.ping() |
266 self.connection.ping() |
260 'conv': django_conversions, |
276 'conv': django_conversions, |
261 'charset': 'utf8', |
277 'charset': 'utf8', |
262 'use_unicode': True, |
278 'use_unicode': True, |
263 } |
279 } |
264 settings_dict = self.settings_dict |
280 settings_dict = self.settings_dict |
265 if settings_dict['DATABASE_USER']: |
281 if settings_dict['USER']: |
266 kwargs['user'] = settings_dict['DATABASE_USER'] |
282 kwargs['user'] = settings_dict['USER'] |
267 if settings_dict['DATABASE_NAME']: |
283 if settings_dict['NAME']: |
268 kwargs['db'] = settings_dict['DATABASE_NAME'] |
284 kwargs['db'] = settings_dict['NAME'] |
269 if settings_dict['DATABASE_PASSWORD']: |
285 if settings_dict['PASSWORD']: |
270 kwargs['passwd'] = settings_dict['DATABASE_PASSWORD'] |
286 kwargs['passwd'] = settings_dict['PASSWORD'] |
271 if settings_dict['DATABASE_HOST'].startswith('/'): |
287 if settings_dict['HOST'].startswith('/'): |
272 kwargs['unix_socket'] = settings_dict['DATABASE_HOST'] |
288 kwargs['unix_socket'] = settings_dict['HOST'] |
273 elif settings_dict['DATABASE_HOST']: |
289 elif settings_dict['HOST']: |
274 kwargs['host'] = settings_dict['DATABASE_HOST'] |
290 kwargs['host'] = settings_dict['HOST'] |
275 if settings_dict['DATABASE_PORT']: |
291 if settings_dict['PORT']: |
276 kwargs['port'] = int(settings_dict['DATABASE_PORT']) |
292 kwargs['port'] = int(settings_dict['PORT']) |
277 # We need the number of potentially affected rows after an |
293 # We need the number of potentially affected rows after an |
278 # "UPDATE", not the number of changed rows. |
294 # "UPDATE", not the number of changed rows. |
279 kwargs['client_flag'] = CLIENT.FOUND_ROWS |
295 kwargs['client_flag'] = CLIENT.FOUND_ROWS |
280 kwargs.update(settings_dict['DATABASE_OPTIONS']) |
296 kwargs.update(settings_dict['OPTIONS']) |
281 self.connection = Database.connect(**kwargs) |
297 self.connection = Database.connect(**kwargs) |
282 self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode] |
298 self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode] |
283 self.connection.encoders[SafeString] = self.connection.encoders[str] |
299 self.connection.encoders[SafeString] = self.connection.encoders[str] |
284 connection_created.send(sender=self.__class__) |
300 connection_created.send(sender=self.__class__) |
285 cursor = CursorWrapper(self.connection.cursor()) |
301 cursor = CursorWrapper(self.connection.cursor()) |