Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
99c87f14
Kaydet (Commit)
99c87f14
authored
Eyl 24, 2013
tarafından
Michael Manfre
Kaydeden (comit)
Anssi Kääriäinen
Eyl 25, 2013
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #17671 - Cursors are now context managers.
üst
04a2a6b0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
86 additions
and
1 deletion
+86
-1
__init__.py
django/db/backends/__init__.py
+4
-1
base.py
django/db/backends/postgresql_psycopg2/base.py
+2
-0
utils.py
django/db/backends/utils.py
+8
-0
1.7.txt
docs/releases/1.7.txt
+19
-0
sql.txt
docs/topics/db/sql.txt
+28
-0
tests.py
tests/backends/tests.py
+25
-0
No files found.
django/db/backends/__init__.py
Dosyayı görüntüle @
99c87f14
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
...
...
@@ -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
...
...
django/db/backends/postgresql_psycopg2/base.py
Dosyayı görüntüle @
99c87f14
...
...
@@ -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
...
...
@@ -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
):
...
...
django/db/backends/utils.py
Dosyayı görüntüle @
99c87f14
...
...
@@ -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
):
...
...
docs/releases/1.7.txt
Dosyayı görüntüle @
99c87f14
...
...
@@ -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
~~~~~~~~~~~~~~
...
...
docs/topics/db/sql.txt
Dosyayı görüntüle @
99c87f14
...
...
@@ -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
tests/backends/tests.py
Dosyayı görüntüle @
99c87f14
...
...
@@ -613,6 +613,31 @@ class BackendTestCase(TestCase):
with
self
.
assertRaises
(
DatabaseError
):
cursor
.
execute
(
query
)
def
test_cursor_contextmanager
(
self
):
"""
Test that cursors can be used as a context manager
"""
with
connection
.
cursor
()
as
cursor
:
from
django.db.backends.util
import
CursorWrapper
self
.
assertTrue
(
isinstance
(
cursor
,
CursorWrapper
))
# Both InterfaceError and ProgrammingError seem to be used when
# accessing closed cursor (psycopg2 has InterfaceError, rest seem
# to use ProgrammingError).
with
self
.
assertRaises
(
connection
.
features
.
closed_cursor_error_class
):
# cursor should be closed, so no queries should be possible.
cursor
.
execute
(
"select 1"
)
@unittest.skipUnless
(
connection
.
vendor
==
'postgresql'
,
"Psycopg2 specific cursor.closed attribute needed"
)
def
test_cursor_contextmanager_closing
(
self
):
# There isn't a generic way to test that cursors are closed, but
# psycopg2 offers us a way to check that by closed attribute.
# So, run only on psycopg2 for that reason.
with
connection
.
cursor
()
as
cursor
:
from
django.db.backends.util
import
CursorWrapper
self
.
assertTrue
(
isinstance
(
cursor
,
CursorWrapper
))
self
.
assertTrue
(
cursor
.
closed
)
# We don't make these tests conditional because that means we would need to
# check and differentiate between:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment