Loading django/db/backends/__init__.py +4 −1 Original line number Diff line number Diff line import datetime import time from django.db.utils import DatabaseError from django.db.utils import DatabaseError, ProgrammingError try: from django.utils.six.moves import _thread as thread Loading Loading @@ -664,6 +664,9 @@ class BaseDatabaseFeatures(object): # Does the backend require a connection reset after each material schema change? connection_persists_old_columns = False # What kind of error does the backend throw when accessing closed cursor? closed_cursor_error_class = ProgrammingError def __init__(self, connection): self.connection = connection Loading django/db/backends/postgresql_psycopg2/base.py +2 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation from django.db.backends.postgresql_psycopg2.version import get_version from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor from django.db.utils import InterfaceError from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeText, SafeBytes Loading Loading @@ -60,6 +61,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): can_rollback_ddl = True supports_combined_alters = True nulls_order_largest = True closed_cursor_error_class = InterfaceError class DatabaseWrapper(BaseDatabaseWrapper): Loading django/db/backends/utils.py +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,14 @@ class CursorWrapper(object): def __iter__(self): return iter(self.cursor) def __enter__(self): return self def __exit__(self, type, value, traceback): # Ticket #17671 - Close instead of passing thru to avoid backend # specific behavior. self.close() class CursorDebugWrapper(CursorWrapper): Loading docs/releases/1.7.txt +19 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,25 @@ In addition, the widgets now display a help message when the browser and server time zone are different, to clarify how the value inserted in the field will be interpreted. Using database cursors as context managers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prior to Python 2.7, database cursors could be used as a context manager. The specific backend's cursor defined the behavior of the context manager. The behavior of magic method lookups was changed with Python 2.7 and cursors were no longer usable as context managers. Django 1.7 allows a cursor to be used as a context manager that is a shortcut for the following, instead of backend specific behavior. .. code-block:: python c = connection.cursor() try: c.execute(...) finally: c.close() Minor features ~~~~~~~~~~~~~~ Loading docs/topics/db/sql.txt +27 −0 Original line number Diff line number Diff line Loading @@ -297,3 +297,30 @@ database library will automatically escape your parameters as necessary. Also note that Django expects the ``"%s"`` placeholder, *not* the ``"?"`` placeholder, which is used by the SQLite Python bindings. This is for the sake of consistency and sanity. .. versionchanged:: 1.7 :pep:`249` does not state whether a cursor should be usable as a context manager. Prior to Python 2.7, a cursor was usable as a context manager due an unexpected behavior in magic method lookups (`Python ticket #9220`_). Django 1.7 explicitly added support to allow using a cursor as context manager. .. _`Python ticket #9220`: http://bugs.python.org/issue9220 Using a cursor as a context manager: .. code-block:: python with connection.cursor() as c: c.execute(...) is equivalent to: .. code-block:: python c = connection.cursor() try: c.execute(...) finally: c.close() No newline at end of file Loading
django/db/backends/__init__.py +4 −1 Original line number Diff line number Diff line import datetime import time from django.db.utils import DatabaseError from django.db.utils import DatabaseError, ProgrammingError try: from django.utils.six.moves import _thread as thread Loading Loading @@ -664,6 +664,9 @@ class BaseDatabaseFeatures(object): # Does the backend require a connection reset after each material schema change? connection_persists_old_columns = False # What kind of error does the backend throw when accessing closed cursor? closed_cursor_error_class = ProgrammingError def __init__(self, connection): self.connection = connection Loading
django/db/backends/postgresql_psycopg2/base.py +2 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation from django.db.backends.postgresql_psycopg2.version import get_version from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor from django.db.utils import InterfaceError from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeText, SafeBytes Loading Loading @@ -60,6 +61,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): can_rollback_ddl = True supports_combined_alters = True nulls_order_largest = True closed_cursor_error_class = InterfaceError class DatabaseWrapper(BaseDatabaseWrapper): Loading
django/db/backends/utils.py +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,14 @@ class CursorWrapper(object): def __iter__(self): return iter(self.cursor) def __enter__(self): return self def __exit__(self, type, value, traceback): # Ticket #17671 - Close instead of passing thru to avoid backend # specific behavior. self.close() class CursorDebugWrapper(CursorWrapper): Loading
docs/releases/1.7.txt +19 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,25 @@ In addition, the widgets now display a help message when the browser and server time zone are different, to clarify how the value inserted in the field will be interpreted. Using database cursors as context managers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prior to Python 2.7, database cursors could be used as a context manager. The specific backend's cursor defined the behavior of the context manager. The behavior of magic method lookups was changed with Python 2.7 and cursors were no longer usable as context managers. Django 1.7 allows a cursor to be used as a context manager that is a shortcut for the following, instead of backend specific behavior. .. code-block:: python c = connection.cursor() try: c.execute(...) finally: c.close() Minor features ~~~~~~~~~~~~~~ Loading
docs/topics/db/sql.txt +27 −0 Original line number Diff line number Diff line Loading @@ -297,3 +297,30 @@ database library will automatically escape your parameters as necessary. Also note that Django expects the ``"%s"`` placeholder, *not* the ``"?"`` placeholder, which is used by the SQLite Python bindings. This is for the sake of consistency and sanity. .. versionchanged:: 1.7 :pep:`249` does not state whether a cursor should be usable as a context manager. Prior to Python 2.7, a cursor was usable as a context manager due an unexpected behavior in magic method lookups (`Python ticket #9220`_). Django 1.7 explicitly added support to allow using a cursor as context manager. .. _`Python ticket #9220`: http://bugs.python.org/issue9220 Using a cursor as a context manager: .. code-block:: python with connection.cursor() as c: c.execute(...) is equivalent to: .. code-block:: python c = connection.cursor() try: c.execute(...) finally: c.close() No newline at end of file