[1.11.x] Bumped MySQLdb version requirement to 1.2.3.
Older versions don't support Python 2.7.
Partial backport of 2d96c027f5
from master
This commit is contained in:
parent
c94cb4f865
commit
ec0af19f4c
|
@ -42,13 +42,12 @@ from .operations import DatabaseOperations # isort:skip
|
||||||
from .schema import DatabaseSchemaEditor # isort:skip
|
from .schema import DatabaseSchemaEditor # isort:skip
|
||||||
from .validation import DatabaseValidation # isort:skip
|
from .validation import DatabaseValidation # isort:skip
|
||||||
|
|
||||||
# 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
|
version = Database.version_info
|
||||||
if (version < (1, 2, 1) or (
|
if version < (1, 2, 3):
|
||||||
version[:3] == (1, 2, 1) and (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
|
raise ImproperlyConfigured(
|
||||||
raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
|
"MySQLdb/mysqlclient 1.2.3 or newer is required; you have %s"
|
||||||
|
% Database.__version__
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def adapt_datetime_warn_on_aware_datetime(value, conv):
|
def adapt_datetime_warn_on_aware_datetime(value, conv):
|
||||||
|
@ -65,11 +64,11 @@ def adapt_datetime_warn_on_aware_datetime(value, conv):
|
||||||
return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S.%f"), conv)
|
return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S.%f"), conv)
|
||||||
|
|
||||||
|
|
||||||
# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like
|
# MySQLdb returns TIME columns as timedelta -- they are more like timedelta in
|
||||||
# timedelta in terms of actual behavior as they are signed and include days --
|
# terms of actual behavior as they are signed and include days -- and Django
|
||||||
# and Django expects time, so we still need to override that. We also need to
|
# expects time, so we still need to override that. We also need to add special
|
||||||
# add special handling for SafeText and SafeBytes as MySQLdb's type
|
# handling for SafeText and SafeBytes as MySQLdb's type checking is too tight
|
||||||
# checking is too tight to catch those (see Django ticket #6052).
|
# to catch those (see Django ticket #6052).
|
||||||
django_conversions = conversions.copy()
|
django_conversions = conversions.copy()
|
||||||
django_conversions.update({
|
django_conversions.update({
|
||||||
FIELD_TYPE.TIME: backend_utils.typecast_time,
|
FIELD_TYPE.TIME: backend_utils.typecast_time,
|
||||||
|
@ -83,13 +82,6 @@ django_conversions.update({
|
||||||
server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
|
server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
|
||||||
|
|
||||||
|
|
||||||
# MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on
|
|
||||||
# MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the
|
|
||||||
# point is to raise Warnings as exceptions, this can be done with the Python
|
|
||||||
# warning module, and this is setup when the connection is created, and the
|
|
||||||
# standard backend_utils.CursorDebugWrapper can be used. Also, using sql_mode
|
|
||||||
# TRADITIONAL will automatically cause most warnings to be treated as errors.
|
|
||||||
|
|
||||||
class CursorWrapper(object):
|
class CursorWrapper(object):
|
||||||
"""
|
"""
|
||||||
A thin wrapper around MySQLdb's normal cursor class so that we can catch
|
A thin wrapper around MySQLdb's normal cursor class so that we can catch
|
||||||
|
|
|
@ -301,7 +301,7 @@ MySQL Connector/Python includes `its own`_.
|
||||||
MySQLdb
|
MySQLdb
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
Django requires MySQLdb version 1.2.1p2 or later.
|
Django requires MySQLdb version 1.2.3 or later.
|
||||||
|
|
||||||
At the time of writing, the latest release of MySQLdb (1.2.5) doesn't support
|
At the time of writing, the latest release of MySQLdb (1.2.5) doesn't support
|
||||||
Python 3. In order to use MySQLdb under Python 3, you'll have to install
|
Python 3. In order to use MySQLdb under Python 3, you'll have to install
|
||||||
|
@ -319,9 +319,8 @@ Python 3. In order to use MySQLdb under Python 3, you'll have to install
|
||||||
mysqlclient
|
mysqlclient
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
Django requires `mysqlclient`_ 1.3.3 or later. Note that Python 3.2 is not
|
Django requires `mysqlclient`_ 1.3.3 or later. mysqlclient should mostly behave
|
||||||
supported. Except for the Python 3.3+ support, mysqlclient should mostly behave
|
the same as MySQLdb.
|
||||||
the same as MySQLDB.
|
|
||||||
|
|
||||||
MySQL Connector/Python
|
MySQL Connector/Python
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -374,46 +373,9 @@ comparisons being done in a *case-insensitive* manner. That is, ``"Fred"`` and
|
||||||
``"freD"`` are considered equal at the database level. If you have a unique
|
``"freD"`` are considered equal at the database level. If you have a unique
|
||||||
constraint on a field, it would be illegal to try to insert both ``"aa"`` and
|
constraint on a field, it would be illegal to try to insert both ``"aa"`` and
|
||||||
``"AA"`` into the same column, since they compare as equal (and, hence,
|
``"AA"`` into the same column, since they compare as equal (and, hence,
|
||||||
non-unique) with the default collation.
|
non-unique) with the default collation. If you want case-sensitive comparisons
|
||||||
|
on a particular column or table, change the column or table to use the
|
||||||
In many cases, this default will not be a problem. However, if you really want
|
``utf8_bin`` collation.
|
||||||
case-sensitive comparisons on a particular column or table, you would change
|
|
||||||
the column or table to use the ``utf8_bin`` collation. The main thing to be
|
|
||||||
aware of in this case is that if you are using MySQLdb 1.2.2, the database
|
|
||||||
backend in Django will then return bytestrings (instead of unicode strings) for
|
|
||||||
any character fields it receive from the database. This is a strong variation
|
|
||||||
from Django's normal practice of *always* returning unicode strings. It is up
|
|
||||||
to you, the developer, to handle the fact that you will receive bytestrings if
|
|
||||||
you configure your table(s) to use ``utf8_bin`` collation. Django itself should
|
|
||||||
mostly work smoothly with such columns (except for the ``contrib.sessions``
|
|
||||||
``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but
|
|
||||||
your code must be prepared to call ``django.utils.encoding.force_text()`` at
|
|
||||||
times if it really wants to work with consistent data -- Django will not do
|
|
||||||
this for you (the database backend layer and the model population layer are
|
|
||||||
separated internally so the database layer doesn't know it needs to make this
|
|
||||||
conversion in this one particular case).
|
|
||||||
|
|
||||||
If you're using MySQLdb 1.2.1p2, Django's standard
|
|
||||||
:class:`~django.db.models.CharField` class will return unicode strings even
|
|
||||||
with ``utf8_bin`` collation. However, :class:`~django.db.models.TextField`
|
|
||||||
fields will be returned as an ``array.array`` instance (from Python's standard
|
|
||||||
``array`` module). There isn't a lot Django can do about that, since, again,
|
|
||||||
the information needed to make the necessary conversions isn't available when
|
|
||||||
the data is read in from the database. This problem was `fixed in MySQLdb
|
|
||||||
1.2.2`_, so if you want to use :class:`~django.db.models.TextField` with
|
|
||||||
``utf8_bin`` collation, upgrading to version 1.2.2 and then dealing with the
|
|
||||||
bytestrings (which shouldn't be too difficult) as described above is the
|
|
||||||
recommended solution.
|
|
||||||
|
|
||||||
Should you decide to use ``utf8_bin`` collation for some of your tables with
|
|
||||||
MySQLdb 1.2.1p2 or 1.2.2, you should still use ``utf8_general_ci``
|
|
||||||
(the default) collation for the ``django.contrib.sessions.models.Session``
|
|
||||||
table (usually called ``django_session``) and the
|
|
||||||
:class:`django.contrib.admin.models.LogEntry` table (usually called
|
|
||||||
``django_admin_log``). Those are the two standard tables that use
|
|
||||||
:class:`~django.db.models.TextField` internally.
|
|
||||||
|
|
||||||
.. _fixed in MySQLdb 1.2.2: http://sourceforge.net/tracker/index.php?func=detail&aid=1495765&group_id=22307&atid=374932
|
|
||||||
|
|
||||||
Please note that according to `MySQL Unicode Character Sets`_, comparisons for
|
Please note that according to `MySQL Unicode Character Sets`_, comparisons for
|
||||||
the ``utf8_general_ci`` collation are faster, but slightly less correct, than
|
the ``utf8_general_ci`` collation are faster, but slightly less correct, than
|
||||||
|
@ -467,12 +429,11 @@ Here's a sample configuration which uses a MySQL option file::
|
||||||
password = PASSWORD
|
password = PASSWORD
|
||||||
default-character-set = utf8
|
default-character-set = utf8
|
||||||
|
|
||||||
Several other MySQLdb connection options may be useful, such as ``ssl``,
|
Several other `MySQLdb connection options`_ may be useful, such as ``ssl``,
|
||||||
``init_command``, and ``sql_mode``. Consult the `MySQLdb documentation`_ for
|
``init_command``, and ``sql_mode``.
|
||||||
more details.
|
|
||||||
|
|
||||||
.. _MySQL option file: https://dev.mysql.com/doc/refman/en/option-files.html
|
.. _MySQL option file: https://dev.mysql.com/doc/refman/en/option-files.html
|
||||||
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
|
.. _MySQLdb connection options: https://mysqlclient.readthedocs.io/en/latest/user_guide.html#functions-and-attributes
|
||||||
|
|
||||||
.. _mysql-sql-mode:
|
.. _mysql-sql-mode:
|
||||||
|
|
||||||
|
|
|
@ -473,13 +473,6 @@ The default form widget for this field is a :class:`~django.forms.TextInput`.
|
||||||
``max_length`` for some backends. Refer to the :doc:`database backend
|
``max_length`` for some backends. Refer to the :doc:`database backend
|
||||||
notes </ref/databases>` for details.
|
notes </ref/databases>` for details.
|
||||||
|
|
||||||
.. admonition:: MySQL users
|
|
||||||
|
|
||||||
If you are using this field with MySQLdb 1.2.2 and the ``utf8_bin``
|
|
||||||
collation (which is *not* the default), there are some issues to be aware
|
|
||||||
of. Refer to the :ref:`MySQL database notes <mysql-collation>` for
|
|
||||||
details.
|
|
||||||
|
|
||||||
``CommaSeparatedIntegerField``
|
``CommaSeparatedIntegerField``
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
@ -1097,13 +1090,6 @@ If you specify a ``max_length`` attribute, it will be reflected in the
|
||||||
However it is not enforced at the model or database level. Use a
|
However it is not enforced at the model or database level. Use a
|
||||||
:class:`CharField` for that.
|
:class:`CharField` for that.
|
||||||
|
|
||||||
.. admonition:: MySQL users
|
|
||||||
|
|
||||||
If you are using this field with MySQLdb 1.2.1p2 and the ``utf8_bin``
|
|
||||||
collation (which is *not* the default), there are some issues to be aware
|
|
||||||
of. Refer to the :ref:`MySQL database notes <mysql-collation>` for
|
|
||||||
details.
|
|
||||||
|
|
||||||
``TimeField``
|
``TimeField``
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue