[1.8.x] Fixed #24335 -- Bumped required psycopg2 version to 2.4.5 (2.5 for contrib.postgres).

Backport of 3adc5f1ee6 from master
This commit is contained in:
Tim Graham 2015-02-16 12:11:39 -05:00
parent d027993ed1
commit 730fb593ad
6 changed files with 33 additions and 33 deletions

View File

@ -5,6 +5,7 @@ Requires psycopg 2: http://initd.org/projects/psycopg2
"""
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.base.validation import BaseDatabaseValidation
from django.utils.encoding import force_str
@ -16,9 +17,19 @@ try:
import psycopg2.extensions
import psycopg2.extras
except ImportError as e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)
def psycopg2_version():
version = psycopg2.__version__.split(' ', 1)[0]
return tuple(int(v) for v in version.split('.') if v.isdigit())
PSYCOPG2_VERSION = psycopg2_version()
if PSYCOPG2_VERSION < (2, 4, 5):
raise ImproperlyConfigured("psycopg2_version 2.4.5 or newer is required; you have %s" % psycopg2.__version__)
# Some of these import psycopg2, so import them after checking if it's installed.
from .client import DatabaseClient # isort:skip
from .creation import DatabaseCreation # isort:skip
@ -164,20 +175,15 @@ class DatabaseWrapper(BaseDatabaseWrapper):
# - after connecting to the database in order to obtain the database's
# default when no value is explicitly specified in options.
# - before calling _set_autocommit() because if autocommit is on, that
# will set connection.isolation_level to ISOLATION_LEVEL_AUTOCOMMIT;
# and if autocommit is off, on psycopg2 < 2.4.2, _set_autocommit()
# needs self.isolation_level.
# will set connection.isolation_level to ISOLATION_LEVEL_AUTOCOMMIT.
options = self.settings_dict['OPTIONS']
try:
self.isolation_level = options['isolation_level']
except KeyError:
self.isolation_level = connection.isolation_level
else:
# Set the isolation level to the value from OPTIONS. This isn't
# needed on psycopg2 < 2.4.2 because it happens as a side-effect
# of _set_autocommit(False).
if (self.isolation_level != connection.isolation_level and
self.psycopg2_version >= (2, 4, 2)):
# Set the isolation level to the value from OPTIONS.
if self.isolation_level != connection.isolation_level:
connection.set_session(isolation_level=self.isolation_level)
return connection
@ -186,13 +192,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
self.connection.set_client_encoding('UTF8')
tz = self.settings_dict['TIME_ZONE']
try:
get_parameter_status = self.connection.get_parameter_status
except AttributeError:
# psycopg2 < 2.0.12 doesn't have get_parameter_status
conn_tz = None
else:
conn_tz = get_parameter_status('TimeZone')
conn_tz = self.connection.get_parameter_status('TimeZone')
if conn_tz != tz:
cursor = self.connection.cursor()
@ -211,14 +211,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def _set_autocommit(self, autocommit):
with self.wrap_database_errors:
if self.psycopg2_version >= (2, 4, 2):
self.connection.autocommit = autocommit
else:
if autocommit:
level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT
else:
level = self.isolation_level
self.connection.set_isolation_level(level)
self.connection.autocommit = autocommit
def check_constraints(self, table_names=None):
"""
@ -239,8 +232,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
@cached_property
def psycopg2_version(self):
version = psycopg2.__version__.split(' ', 1)[0]
return tuple(int(v) for v in version.split('.') if v.isdigit())
return PSYCOPG2_VERSION
@cached_property
def pg_version(self):

View File

@ -1,12 +1,17 @@
``django.contrib.postgres``
===========================
.. module:: django.contrib.postgres
:synopsis: PostgreSQL-specific fields and features
.. versionadded:: 1.8
PostgreSQL has a number of features which are not shared by the other databases
Django supports. This optional module contains model fields and form fields for
a number of PostgreSQL specific data types.
Psycopg2 2.5 or higher is required.
.. note::
Django is, and will continue to be, a database-agnostic web framework. We
would encourage those writing reusable applications for the Django

View File

@ -92,8 +92,10 @@ below for information on how to set up your database correctly.
PostgreSQL notes
================
Django supports PostgreSQL 9.0 and higher. It requires the use of Psycopg2
2.0.9 or higher.
Django supports PostgreSQL 9.0 and higher. It requires the use of `psycopg2`_
2.4.5 or higher (or 2.5+ if you want to use :mod:`django.contrib.postgres`).
.. _psycopg2: http://initd.org/psycopg/
If you're on Windows, check out the unofficial `compiled Windows version`_
of psycopg2.

View File

@ -833,7 +833,8 @@ officially supports.
This also includes dropping support for PostGIS 1.3 and 1.4 as these versions
are not supported on versions of PostgreSQL later than 8.4.
Django also now requires the use of Psycopg2 version 2.0.9 or higher.
Django also now requires the use of Psycopg2 version 2.4.5 or higher (or 2.5+
if you want to use :mod:`django.contrib.postgres`).
Support for MySQL versions older than 5.5
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -290,14 +290,14 @@ class PostgreSQLTests(TestCase):
self.assertIn('::text', do.lookup_cast(lookup))
def test_correct_extraction_psycopg2_version(self):
from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper
from django.db.backends.postgresql_psycopg2.base import psycopg2_version
version_path = 'django.db.backends.postgresql_psycopg2.base.Database.__version__'
with mock.patch(version_path, '2.6.9'):
self.assertEqual(DatabaseWrapper.psycopg2_version.__get__(self), (2, 6, 9))
self.assertEqual(psycopg2_version(), (2, 6, 9))
with mock.patch(version_path, '2.5.dev0'):
self.assertEqual(DatabaseWrapper.psycopg2_version.__get__(self), (2, 5))
self.assertEqual(psycopg2_version(), (2, 5))
class DateQuotingTest(TestCase):

View File

@ -1 +1 @@
psycopg2
psycopg2>=2.5