Re: [cx-oracle-users] Help with fetchraw
Brought to you by:
atuining
|
From: Anthony T. <ant...@gm...> - 2005-05-18 06:08:06
|
On 5/17/05, Chris Dunscombe <cdu...@ya...> wrote:
>=20
> --- Anthony Tuininga <ant...@gm...> wrote:
> > 1) You should be able to do something like this without the need to
> > descend into fetchraw().
> >
> > import cx_Oracle
> >
> > fromConnection =3D cx_Oracle.Connection("user/pw@tns")
> > toConnection =3D cx_Oracle.Connection("user/pw@tns")
> > fromCursor =3D fromConnection.cursor()
> > fromCursor.arraysize =3D 250 # set as desired
> > toCursor =3D toConnection.cursor()
> > toCursor.arraysize =3D 250 # set as desired, same as fromCursor
> >
> > fromCursor.execute("some query")
> > toCursor.setinputsizes() # set things up if nulls are allowed
> > while True:
> > data =3D fromCursor.fetchmany()
> > if not data:
> > break
> > toCursor.executemany("some insert statement", data)
> > toConnection.commit() # if desired
> >
> > That should do it and should perform quite well. The fetchraw(),
> > bindvar.copy() and executemanyprepared() trio were created solely to
> > avoid the overhead of creating Python objects for the data. Its more
> > complicated than the above code but I can give that as an example as
> > well if you really want it.
> >
>=20
> I've done essentially the same as you've got above and yes it works fine =
with pretty good
> performance. I'm just trying to improve it further as there are cases whe=
n the app will be running
> a number of parallel streams each selecting and inserting millions of row=
s in a fixed window so
> saving 5% - 15% of the Python CPU time within this loop is definately wor=
th doing. I'd like a
> fetchraw example so I can benchmark it against my current approach. I'll =
then post the results so
> everyone can see the general sort of performance differences between the =
two.
The following is the code for using fetchraw(). My own preliminary
results show that in fact it is slower than the original method above
that I showed you and is more complicated to boot. The fact that the
data can be passed from the one cursor to the other directly and that
the bindvar.copy() command must be called for each bind variable for
each row makes the overhead of fetching Python objects less than the
overhead of calling the bindvar.copy() methods. The fetchraw() method
was considerably faster when lists of dictionaries needed to be passed
through to executemany().
import cx_Oracle
sourceConnection =3D cx_Oracle.Connection("user/pw@tns")
sourceCursor =3D sourceConnection.cursor()
sourceCursor.arraysize =3D 250
sourceVars =3D sourceCursor.execute("select * from testdata_source")
targetConnection =3D cx_Oracle.Connection("user/pw@tns")
targetCursor =3D targetConnection.cursor()
targetCursor.execute("truncate table testdata_copy")
targetCursor.arraysize =3D 250
targetVars =3D targetCursor.setinputsizes(cx_Oracle.NUMBER, cx_Oracle.DATET=
IME,
cx_Oracle.NUMBER, cx_Oracle.STRING)
targetCursor.prepare("insert into testdata_copy values (:1, :2, :3, :4)")
vars =3D zip(sourceVars, targetVars)
indexes =3D range(sourceCursor.arraysize)
while True:
rowsFetched =3D sourceCursor.fetchraw()
print "fetched", rowsFetched, "rows"
if not rowsFetched:
break
if rowsFetched !=3D sourceCursor.arraysize:
indexes =3D range(rowsFetched)
for index in indexes:
for sourceVar, targetVar in vars:
targetVar.copy(sourceVar, index, index)
targetCursor.executemanyprepared(rowsFetched)
targetConnection.commit()
Another method which also works but only when the exact data is being
replicated from one cursor to another is the following. It is faster
than both methods but limited in usefulness of course.
import cx_Oracle
sourceConnection =3D cx_Oracle.Connection("user/pw@tns")
sourceCursor =3D sourceConnection.cursor()
sourceCursor.arraysize =3D 250
sourceVars =3D sourceCursor.execute("select * from testdata_source")
targetConnection =3D cx_Oracle.Connection("user/pw@tns")
targetCursor =3D targetConnection.cursor()
targetCursor.execute("truncate table testdata_copy")
targetCursor.arraysize =3D 250
targetVars =3D targetCursor.setinputsizes(*sourceVars)
targetCursor.prepare("insert into testdata_copy values (:1, :2, :3, :4)")
while True:
rowsFetched =3D sourceCursor.fetchraw()
print "fetched", rowsFetched, "rows"
if not rowsFetched:
break
targetCursor.executemanyprepared(rowsFetched)
targetConnection.commit()
Hope this helps,
Anthony
|