Mati Skiva wrote:
> from inspecting mapper.py's _save_obj method, I found that after every
> insert the following items are required:
>
>     * value_params - used by _postfetch
>     * params - used by _postfetch
>     * ResultProxy.last_inserted_params() - used by _postfetch
>     * ResultProxy.postfetch_cols() - used within _postfetch
>     * ResultProxy.prefetch_cols() - used within _postfetch
>     * ResultProxy.last_inserted_ids() - used by by _save_obj
>
> All of these items shared the same problem, they are all dictionaries or
> lists. One for each insert, making them single-dimension data (in
> respect to the insert).
> But when executing many, they became either None or kept their
> single-dimension property (i.e. for two inserts, only one list is
> returned, when I expect a list of lists)

the cols() methods return lists of column objects which correspond to the
structure of the insert.  Those apply to executemany() as well as
execute(), since both functions receive a single insert() construct of a
fixed form.   The value_params() similarly are fixed for the single insert
construct and do not change.    last_inserted_ids() is not used in your
recipe - you are calculating primary key values en masse - DBAPI has no
way to give you this information.   The only value here that may be of
usage is last_inserted_params().  The only data in that collection which
is not present before the insert is executed are Python side defaults
which you may have configured on your Table.    The full list of
everything inserted post-calculation of python-side defaults is present at
resultproxy.context.compiled_parameters.   Use 0.6, the code example you
mention is obsolete 0.5 code, and the compiled_parameters collection is
undisturbed.

>
> I was forced to make one extra change, for sqlite.py's post_exec method.
> Basically, populating the self._last_inserted_ids attribute. But for
> some reason self.cursor.lastrowid is None for execute-many (while it can

Here is the reason:

http://www.python.org/dev/peps/pep-0249/

Cursor Attribute .lastrowid

        This read-only attribute provides the rowid of the last
        modified row (most databases return a rowid only when a single
        INSERT operation is performed). If the operation does not set
        a rowid or if the database does not support rowids, this
        attribute should be set to None.

        The semantics of .lastrowid are undefined in case the last
        executed statement modified more than one row, e.g. when
        using INSERT with .executemany().

Also be aware that .lastrowid is not implemented at all for:

psycopg2, pg8000, cx_oracle, kintersbasdb, pyodbc, pymssql, adodbapi, etc.

I'm strongly opposed to forcing a multi-row version of last_inserted_ids()
into dialects.   It cannot work consistently or predictably, and is not
supported by DBAPI.

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

Reply via email to