summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2012-04-21 03:04:10 +0000
committerRamiro Morales <cramm0@gmail.com>2012-04-21 03:04:10 +0000
commit4536359887b34eea5e7b8cf6864d9092b46c2980 (patch)
tree4c30dfa4479708b347f5b56dc296f43981281ae9
parent53fb45c6d82da6136bd06c0318c364fd076e67be (diff)
Fixed #18116 -- Raised minimum MySQL version officially suported to 5.0.3.
Thanks Carl, Claude and Anssi for discussion and patch review. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17921 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/backends/mysql/base.py12
-rw-r--r--django/db/backends/mysql/introspection.py29
-rw-r--r--django/db/backends/mysql/validation.py29
-rw-r--r--docs/ref/databases.txt33
4 files changed, 32 insertions, 71 deletions
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index faaefca06b..c1ef625bb6 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -15,11 +15,13 @@ except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
+from django.utils.functional import cached_property
+
# We want version (1, 2, 1, 'final', 2) or later. We can't just use
# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
# inadvertently passes the version test.
version = Database.version_info
-if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
+if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
(len(version) < 5 or version[3] != 'final' or version[4] < 2))):
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
@@ -163,6 +165,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_timezones = False
requires_explicit_null_ordering_when_grouping = True
allows_primary_key_0 = False
+ uses_savepoints = True
def __init__(self, connection):
super(DatabaseFeatures, self).__init__(connection)
@@ -387,8 +390,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
self.connection = Database.connect(**kwargs)
self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
self.connection.encoders[SafeString] = self.connection.encoders[str]
- self.features.uses_savepoints = \
- self.get_server_version() >= (5, 0, 3)
connection_created.send(sender=self.__class__, connection=self)
cursor = self.connection.cursor()
if new_connection:
@@ -405,10 +406,11 @@ class DatabaseWrapper(BaseDatabaseWrapper):
except Database.NotSupportedError:
pass
- def get_server_version(self):
+ @cached_property
+ def mysql_version(self):
if not self.server_version:
if not self._valid_connection():
- self.cursor()
+ self.cursor().close()
m = server_version_re.match(self.connection.get_server_info())
if not m:
raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info())
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index ab4eebea90..bb56ae38a6 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -65,27 +65,14 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
key columns in given table.
"""
key_columns = []
- try:
- cursor.execute("""
- SELECT column_name, referenced_table_name, referenced_column_name
- FROM information_schema.key_column_usage
- WHERE table_name = %s
- AND table_schema = DATABASE()
- AND referenced_table_name IS NOT NULL
- AND referenced_column_name IS NOT NULL""", [table_name])
- key_columns.extend(cursor.fetchall())
- except (ProgrammingError, OperationalError):
- # Fall back to "SHOW CREATE TABLE", for previous MySQL versions.
- # Go through all constraints and save the equal matches.
- cursor.execute("SHOW CREATE TABLE %s" % self.connection.ops.quote_name(table_name))
- for row in cursor.fetchall():
- pos = 0
- while True:
- match = foreign_key_re.search(row[1], pos)
- if match == None:
- break
- pos = match.end()
- key_columns.append(match.groups())
+ cursor.execute("""
+ SELECT column_name, referenced_table_name, referenced_column_name
+ FROM information_schema.key_column_usage
+ WHERE table_name = %s
+ AND table_schema = DATABASE()
+ AND referenced_table_name IS NOT NULL
+ AND referenced_column_name IS NOT NULL""", [table_name])
+ key_columns.extend(cursor.fetchall())
return key_columns
def get_primary_key_column(self, cursor, table_name):
diff --git a/django/db/backends/mysql/validation.py b/django/db/backends/mysql/validation.py
index 663cc7da4e..de7474d1e5 100644
--- a/django/db/backends/mysql/validation.py
+++ b/django/db/backends/mysql/validation.py
@@ -3,30 +3,13 @@ from django.db.backends import BaseDatabaseValidation
class DatabaseValidation(BaseDatabaseValidation):
def validate_field(self, errors, opts, f):
"""
- There are some field length restrictions for MySQL:
-
- - Prior to version 5.0.3, character fields could not exceed 255
- characters in length.
- - No character (varchar) fields can have a length exceeding 255
- characters if they have a unique index on them.
+ MySQL has the following field length restriction:
+ No character (varchar) fields can have a length exceeding 255
+ characters if they have a unique index on them.
"""
from django.db import models
- from MySQLdb import OperationalError
- try:
- db_version = self.connection.get_server_version()
- text_version = '.'.join([str(n) for n in db_version[:3]])
- except OperationalError:
- db_version = None
- text_version = ''
varchar_fields = (models.CharField, models.CommaSeparatedIntegerField,
models.SlugField)
- if isinstance(f, varchar_fields) and f.max_length > 255:
- if db_version and db_version < (5, 0, 3):
- msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %(version)s).'
- elif f.unique == True:
- msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when using "unique=True".'
- else:
- msg = None
-
- if msg:
- errors.add(opts, msg % {'name': f.name, 'cls': f.__class__.__name__, 'version': text_version})
+ if isinstance(f, varchar_fields) and f.max_length > 255 and f.unique:
+ msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when using "unique=True".'
+ errors.add(opts, msg % {'name': f.name, 'cls': f.__class__.__name__})
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index 59a0c36ad6..c271946bb7 100644
--- a/docs/ref/databases.txt
+++ b/docs/ref/databases.txt
@@ -122,30 +122,23 @@ lookups that use the ``LIKE`` operator in their SQL, as is done with the
MySQL notes
===========
-Django expects the database to support transactions, referential integrity, and
-Unicode (UTF-8 encoding). Fortunately, MySQL_ has all these features as
-available as far back as 3.23. While it may be possible to use 3.23 or 4.0,
-you'll probably have less trouble if you use 4.1 or 5.0.
+Version support
+---------------
-MySQL 4.1
----------
+Django supports MySQL 5.0.3 and higher.
-`MySQL 4.1`_ has greatly improved support for character sets. It is possible to
-set different default character sets on the database, table, and column.
-Previous versions have only a server-wide character set setting. It's also the
-first version where the character set can be changed on the fly. 4.1 also has
-support for views, but Django currently doesn't use views.
+`MySQL 5.0`_ adds the ``information_schema`` database, which contains detailed
+data on all database schema. Django's ``inspectdb`` feature uses this feature.
-MySQL 5.0
----------
+.. versionchanged:: 1.5
+ The minimum version requirement of MySQL 5.0.3 was set in Django 1.5.
-`MySQL 5.0`_ adds the ``information_schema`` database, which contains detailed
-data on all database schema. Django's ``inspectdb`` feature uses this
-``information_schema`` if it's available. 5.0 also has support for stored
-procedures, but Django currently doesn't use stored procedures.
+Django expects the database to support Unicode (UTF-8 encoding) and delegates to
+it the task of enforcing transactions and referential integrity. It is important
+to be aware of the fact that the two latter ones aren't actually enforced by
+MySQL when using the MyISAM storage engine, see the next section.
.. _MySQL: http://www.mysql.com/
-.. _MySQL 4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html
.. _MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html
Storage engines
@@ -381,10 +374,6 @@ for the field. This affects :class:`~django.db.models.CharField`,
:class:`~django.db.models.SlugField` and
:class:`~django.db.models.CommaSeparatedIntegerField`.
-Furthermore, if you are using a version of MySQL prior to 5.0.3, all of those
-column types have a maximum length restriction of 255 characters, regardless
-of whether ``unique=True`` is specified or not.
-
DateTime fields
~~~~~~~~~~~~~~~