#10320: CursorDebugWrapper should allow using iterators/generators for
executemany().
-------------------------------------+-------------------------------------
     Reporter:  MockSoul             |                    Owner:  nobody
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:  1.0
  (models, ORM)                      |               Resolution:
     Severity:  Normal               |             Triage Stage:  Design
     Keywords:                       |  decision needed
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by aaugustin):

 * ui_ux:   => 0
 * easy:   => 0


Comment:

 Strictly speaking, PEP 249 defines `executemany(operation,
 seq_of_parameters)`, where `seq_of_parameters` is a
 [http://docs.python.org/library/stdtypes.html#sequence-types-str-unicode-
 list-tuple-bytearray-buffer-xrange sequence], and `len` is always
 available on sequences.

 However, three out of four database backends support calling
 `Cursor.executemany` with an iterator as second argument:
 - The built-in `sqlite3` module
 [http://docs.python.org/library/sqlite3#sqlite3.Cursor.executemany also
 allows] using an iterator yielding parameters instead of a sequence.
 - It's clear from the source of pyscopg2, in `cursor_type.c`, that
 `psycopg.Cursor.executemany` accepts iterators, and if it receives a non-
 iterable, it actually converts it to an iterator -- `if
 (!PyIter_Check(vars)) { vars = iter = PyObject_GetIter(vars); ... }`.
 - `MySQLdb.Cursor.executemany` is implemented in Python, and the two
 possible code paths use `for row in args`, which clearly works with
 iterators.
 - Only `cx_Oracle.Cursor.executemany` fails to accept an iterator as
 argument: in `Cursor.c`, `Cursor_ExecuteMany` does `numRows =
 PyList_GET_SIZE(listOfArguments);`

 So, it would be a good idea to support iterators in `CursorDebugWrapper`.
 Note that the performance argument is irrelevant for `CursorDebugWrapper`
 itself, since it's only used when `DEBUG=True`. The real reason for the
 fix is that `CursorDebugWrapper` shouldn't be more restrictive than
 regular cursors.

 NB: `django.db.backends.oracle.base.FormatStylePlaceholderCursor` also
 relies on `params` not being a iterator, since it tries to access
 `params[0]`. But that could be fixed by adding something along the lines
 of `if params is not None: params = list(params)`.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/10320#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to