Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 207 lines (180 sloc) 7.966 kb
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
1 """
2 MySQL database backend for Django.
3
4 Requires MySQLdb: http://sourceforge.net/projects/mysql-python
5 """
6
38b5d7f Adrian Holovaty Began implementing BaseDatabaseOperations class for every database backe...
adrianholovaty authored
7 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseOperations, util
8e9833f Adrian Holovaty Fixed #1673 -- Every database backend now raises ImproperlyConfigured if...
adrianholovaty authored
8 try:
9 import MySQLdb as Database
10 except ImportError, e:
11 from django.core.exceptions import ImproperlyConfigured
12 raise ImproperlyConfigured, "Error loading MySQLdb module: %s" % e
cb624b1 Malcolm Tredinnick Fixed #3747 -- Added a stricter MySQLdb version check so that (1, 2, 1,
malcolmt authored
13
14 # We want version (1, 2, 1, 'final', 2) or later. We can't just use
15 # lexicographic ordering in this check because then (1, 2, 1, 'gamma')
16 # inadvertently passes the version test.
17 version = Database.version_info
92c35a0 Malcolm Tredinnick Fixed #2365, #3324 -- Renamed FloatField to DecimalField and changed the...
malcolmt authored
18 if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
cb624b1 Malcolm Tredinnick Fixed #3747 -- Added a stricter MySQLdb version check so that (1, 2, 1,
malcolmt authored
19 (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
20 raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
21
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
22 from MySQLdb.converters import conversions
23 from MySQLdb.constants import FIELD_TYPE
24 import types
6068f3e Malcolm Tredinnick Reintroduced the changes from [3855] with more flexible handling of vers...
malcolmt authored
25 import re
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
26
27 DatabaseError = Database.DatabaseError
b3e0b59 Malcolm Tredinnick Fixed #3450 -- Exposed IntegrityError in a backend-neutral fashion. This...
malcolmt authored
28 IntegrityError = Database.IntegrityError
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
29
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
30 # MySQLdb-1.2.1 supports the Python boolean type, and only uses datetime
31 # module for time-related columns; older versions could have used mx.DateTime
32 # or strings if there were no datetime module. However, MySQLdb still returns
33 # TIME columns as timedelta -- they are more like timedelta in terms of actual
34 # behavior as they are signed and include days -- and Django expects time, so
35 # we still need to override that.
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
36 django_conversions = conversions.copy()
37 django_conversions.update({
38 FIELD_TYPE.TIME: util.typecast_time,
92c35a0 Malcolm Tredinnick Fixed #2365, #3324 -- Renamed FloatField to DecimalField and changed the...
malcolmt authored
39 FIELD_TYPE.DECIMAL: util.typecast_decimal,
40 FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
41 })
42
6068f3e Malcolm Tredinnick Reintroduced the changes from [3855] with more flexible handling of vers...
malcolmt authored
43 # This should match the numerical portion of the version numbers (we can treat
44 # versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
45 # at http://dev.mysql.com/doc/refman/4.1/en/news.html and
46 # http://dev.mysql.com/doc/refman/5.0/en/news.html .
47 server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
48
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
49 # MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on
50 # MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the
51 # point is to raise Warnings as exceptions, this can be done with the Python
52 # warning module, and this is setup when the connection is created, and the
53 # standard util.CursorDebugWrapper can be used. Also, using sql_mode
54 # TRADITIONAL will automatically cause most warnings to be treated as errors.
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
55
38b5d7f Adrian Holovaty Began implementing BaseDatabaseOperations class for every database backe...
adrianholovaty authored
56 class DatabaseOperations(BaseDatabaseOperations):
aab04a4 Adrian Holovaty Refactored get_date_extract_sql() to DatabaseOperations.date_extract_sql...
adrianholovaty authored
57 def date_extract_sql(self, lookup_type, field_name):
58 # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
59 return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
38b5d7f Adrian Holovaty Began implementing BaseDatabaseOperations class for every database backe...
adrianholovaty authored
60
5f51f05 Adrian Holovaty Refactored get_date_trunc_sql() to DatabaseOperations.date_trunc_sql(). ...
adrianholovaty authored
61 def date_trunc_sql(self, lookup_type, field_name):
62 fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
63 format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
64 format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
65 try:
66 i = fields.index(lookup_type) + 1
67 except ValueError:
68 sql = field_name
69 else:
70 format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
71 sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
72 return sql
73
23a736d Adrian Holovaty Refactored get_drop_foreignkey_sql() to DatabaseOperations.drop_foreignk...
adrianholovaty authored
74 def drop_foreignkey_sql(self):
75 return "DROP FOREIGN KEY"
76
5a64264 Adrian Holovaty Refactored get_fulltext_search_sql() to DatabaseOperations.fulltext_sear...
adrianholovaty authored
77 def fulltext_search_sql(self, field_name):
78 return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
79
d3e69c3 Adrian Holovaty Refactored get_limit_offset_sql() to DatabaseOperations.limit_offset_sql...
adrianholovaty authored
80 def limit_offset_sql(self, limit, offset=None):
81 # 'LIMIT 20,40'
82 sql = "LIMIT "
83 if offset and offset != 0:
84 sql += "%s," % offset
85 return sql + str(limit)
86
221f99e Adrian Holovaty Refactored quote_name() to DatabaseOperations.quote_name(). Refs #5106
adrianholovaty authored
87 def quote_name(self, name):
88 if name.startswith("`") and name.endswith("`"):
89 return name # Quoting once is enough.
90 return "`%s`" % name
91
c44fb66 Adrian Holovaty Refactored get_random_function_sql() to DatabaseOperations.random_functi...
adrianholovaty authored
92 def random_function_sql(self):
93 return 'RAND()'
94
aaed6e0 Adrian Holovaty Refactored get_sql_flush() to DatabaseOperations.sql_flush(). Refs #5106
adrianholovaty authored
95 def sql_flush(self, style, tables, sequences):
96 # NB: The generated SQL below is specific to MySQL
97 # 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
98 # to clear all tables of all data
99 if tables:
100 sql = ['SET FOREIGN_KEY_CHECKS = 0;']
101 for table in tables:
221f99e Adrian Holovaty Refactored quote_name() to DatabaseOperations.quote_name(). Refs #5106
adrianholovaty authored
102 sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(self.quote_name(table))))
aaed6e0 Adrian Holovaty Refactored get_sql_flush() to DatabaseOperations.sql_flush(). Refs #5106
adrianholovaty authored
103 sql.append('SET FOREIGN_KEY_CHECKS = 1;')
104
105 # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements
106 # to reset sequence indices
107 sql.extend(["%s %s %s %s %s;" % \
108 (style.SQL_KEYWORD('ALTER'),
109 style.SQL_KEYWORD('TABLE'),
221f99e Adrian Holovaty Refactored quote_name() to DatabaseOperations.quote_name(). Refs #5106
adrianholovaty authored
110 style.SQL_TABLE(self.quote_name(sequence['table'])),
aaed6e0 Adrian Holovaty Refactored get_sql_flush() to DatabaseOperations.sql_flush(). Refs #5106
adrianholovaty authored
111 style.SQL_KEYWORD('AUTO_INCREMENT'),
112 style.SQL_FIELD('= 1'),
113 ) for sequence in sequences])
114 return sql
115 else:
116 return []
117
7c41b19 Adrian Holovaty Refactored all database backends to inherit from a common base class to ...
adrianholovaty authored
118 class DatabaseWrapper(BaseDatabaseWrapper):
38b5d7f Adrian Holovaty Began implementing BaseDatabaseOperations class for every database backe...
adrianholovaty authored
119 ops = DatabaseOperations()
120
fef89a0 Jacob Kaplan-Moss Fixed #2866: Added DATABASE_OPTIONS setting which gets passed as extra k...
jacobian authored
121 def __init__(self, **kwargs):
7c41b19 Adrian Holovaty Refactored all database backends to inherit from a common base class to ...
adrianholovaty authored
122 super(DatabaseWrapper, self).__init__(**kwargs)
6068f3e Malcolm Tredinnick Reintroduced the changes from [3855] with more flexible handling of vers...
malcolmt authored
123 self.server_version = None
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
124
125 def _valid_connection(self):
126 if self.connection is not None:
127 try:
128 self.connection.ping()
129 return True
130 except DatabaseError:
131 self.connection.close()
132 self.connection = None
133 return False
134
7c41b19 Adrian Holovaty Refactored all database backends to inherit from a common base class to ...
adrianholovaty authored
135 def _cursor(self, settings):
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
136 from warnings import filterwarnings
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
137 if not self._valid_connection():
138 kwargs = {
139 'conv': django_conversions,
1f9711f Malcolm Tredinnick Fixed #3754 -- Re-introduced utf-8 as default encoding for interaction w...
malcolmt authored
140 'charset': 'utf8',
953badb Malcolm Tredinnick Merged Unicode branch into trunk (r4952:5608). This should be fully
malcolmt authored
141 'use_unicode': True,
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
142 }
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
143 if settings.DATABASE_USER:
144 kwargs['user'] = settings.DATABASE_USER
145 if settings.DATABASE_NAME:
146 kwargs['db'] = settings.DATABASE_NAME
147 if settings.DATABASE_PASSWORD:
148 kwargs['passwd'] = settings.DATABASE_PASSWORD
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
149 if settings.DATABASE_HOST.startswith('/'):
150 kwargs['unix_socket'] = settings.DATABASE_HOST
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
151 elif settings.DATABASE_HOST:
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
152 kwargs['host'] = settings.DATABASE_HOST
153 if settings.DATABASE_PORT:
154 kwargs['port'] = int(settings.DATABASE_PORT)
fef89a0 Jacob Kaplan-Moss Fixed #2866: Added DATABASE_OPTIONS setting which gets passed as extra k...
jacobian authored
155 kwargs.update(self.options)
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
156 self.connection = Database.connect(**kwargs)
7c41b19 Adrian Holovaty Refactored all database backends to inherit from a common base class to ...
adrianholovaty authored
157 cursor = self.connection.cursor()
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
158 if settings.DEBUG:
f9c4ce5 Malcolm Tredinnick Fixed #2635 -- Added improved MySQL backend support from Andy Dustman. A...
malcolmt authored
159 filterwarnings("error", category=Database.Warning)
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
160 return cursor
161
162 def _rollback(self):
7c41b19 Adrian Holovaty Refactored all database backends to inherit from a common base class to ...
adrianholovaty authored
163 try:
164 BaseDatabaseWrapper._rollback(self)
165 except Database.NotSupportedError:
166 pass
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
167
6068f3e Malcolm Tredinnick Reintroduced the changes from [3855] with more flexible handling of vers...
malcolmt authored
168 def get_server_version(self):
169 if not self.server_version:
170 if not self._valid_connection():
171 self.cursor()
172 m = server_version_re.match(self.connection.get_server_info())
173 if not m:
174 raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info())
a834f21 Malcolm Tredinnick Fixed omission in [3872].
malcolmt authored
175 self.server_version = tuple([int(x) for x in m.groups()])
6068f3e Malcolm Tredinnick Reintroduced the changes from [3855] with more flexible handling of vers...
malcolmt authored
176 return self.server_version
177
ac64e91 Malcolm Tredinnick Merged boulder-oracle-sprint branch (r3965:5512) back into trunk. All
malcolmt authored
178 allows_group_by_ordinal = True
179 allows_unique_and_pk = True
180 autoindexes_primary_keys = False
181 needs_datetime_string_cast = True # MySQLdb requires a typecast for dates
182 needs_upper_for_iops = False
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
183 supports_constraints = True
ac64e91 Malcolm Tredinnick Merged boulder-oracle-sprint branch (r3965:5512) back into trunk. All
malcolmt authored
184 supports_tablespaces = False
185 uses_case_insensitive_names = False
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
186
187 dictfetchone = util.dictfetchone
188 dictfetchmany = util.dictfetchmany
189 dictfetchall = util.dictfetchall
190
191 OPERATOR_MAPPING = {
192 'exact': '= %s',
193 'iexact': 'LIKE %s',
194 'contains': 'LIKE BINARY %s',
195 'icontains': 'LIKE %s',
24512a7 Jacob Kaplan-Moss Fixed #1465: added support for regex lookups. Thanks, Tom Tobin.
jacobian authored
196 'regex': 'REGEXP BINARY %s',
197 'iregex': 'REGEXP %s',
f69cf70 Adrian Holovaty MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-in...
adrianholovaty authored
198 'gt': '> %s',
199 'gte': '>= %s',
200 'lt': '< %s',
201 'lte': '<= %s',
202 'startswith': 'LIKE BINARY %s',
203 'endswith': 'LIKE BINARY %s',
204 'istartswith': 'LIKE %s',
205 'iendswith': 'LIKE %s',
206 }
Something went wrong with that request. Please try again.