Listados con Reportlab mediante trml2pdf

lasizoillo lasizoillo en gmail.com
Vie Mar 9 11:04:02 CET 2007


Buenas:

Interesante el tema, aunque ya que estamos hablando de optimización,
me gustaria hacer una aportacion.

>
> from psycopg import connect
> import subprocess
> import sys
>
> class prueba:
>     def __init__(self, conexion=None):
>         self.cnx=conexion
>         self.cursor = self.cnx.cursor()
>         for i in range (1, 30000):
>             sql=("insert into test (numero, palabra)values (%s, 'hola')")%i
>             self.cursor.execute(sql)
>
>         self.show()
>
>     def imprime(self):
>         self.cadena = ''
>         self.cadena +='<html>'
>         self.cadena += '<table>'
>         self.cursor.execute ('select * from test')
>         records = self.cursor.fetchall()
>         for record in records:
>             self.cadena += '<tr>'
>             self.cadena += '<td>'
>             self.cadena += '%s, %s</td>' %(record[0], record[1])
>             self.cadena += '</tr>'

Cadena acabara conteniendo todo el reporte en memoria. Esto se puede
evitar con el uso de iteradores:

     def imprime(self):
         yield '<html>...<table>'
         self.cursor.execute ('select * from test')
         records = self.cursor.fetchall()
         for record in records:
             yield  '<tr><td>%s, %s</td></tr>' %(record[0], record[1])
         yield '</table>---</html>'

Ademas evitamos crear/destruir objetos constantemente. Por cada suma
de cadenas, generamos un objeto cadena intermedio, que liberamos
despues con la siguiente creacion de objeto cadena intermedio, ... Un
derroche en la gestión de memoria.

>
>     def show(self):
>         self.imprime()
>         f = open("reporte.html", "w")
>         f.write(self.cadena)
>         f.close()
>         if sys.platform == "win32":
>             subprocess.Popen('explorer reporte.html', shell=True)
>         else:
>             subprocess.Popen('firefox reporte.html', shell=True)
>

     def show(self):
         generador = self.imprime()
         f = open("reporte.html", "w")
         for dato in generador:
             f.write(dato)
         f.close()
         if sys.platform == "win32":
             subprocess.Popen('explorer reporte.html', shell=True)
         else:
             subprocess.Popen('firefox reporte.html', shell=True)

> if __name__ == "__main__":
>     cnx = connect("dbname=prueba")
>     cnx.autocommit()
>     d = prueba(cnx)


>
> El día 28/02/07, Chema Cortes <pych3m4 en gmail.com> escribió:
> >
> > El 27/02/07, Amm-Python <python en ammsoft.com> escribió:
> >
> > > Para 500 registros  2.750s (rápido)
> > > Para 1000 registros 6.063s (bien)
> > > Para 2000 registros 13.797s (empieza a no gustarme)
> > > Para 3000 registros 23.641s (no me gusta)
> > > Para 4000 registros 35.813s (sigue sin gustarme)
> > > Para 5000 registros 50.469s (esto ...)
> > >
> > > (Nota: No hay cabeceras ni pies de página, ni contadores de las mismas,
> > > ni logotipos, etc.)
> > >
> > > Para mi es normal hacer un informe con 10000, 20000, 50000 registros.
> > > Sobretodo informes de resúmenes anuales; seguro que no sirven para nada,
> > > pero a los clientes les encantan.
> > >
> > > Por lo que concluyo que, o el esquema del ejemplo no es eficiente, o yo
> > > no se hacerlo mejor, o debo utilizar otra alternativa para generar el
> > > pdf.
> > >
> > > Mientras sigo exportando datos a formato xls y/o csv.
> > >
> > > Hasta me estoy planteando que el cliente instale LaTex y hacer el
> > > listado en dicho formato. Y antes de planteármelo seriamente, pregunto,
> > > ¿con qué generáis listados de grandes volúmenes de información?.
> >
> > No puedo darte una solución; tan sólo te confirmo que hemos tenido los
> > mismos problemas  para crear ficheros pdf con tantos registros, tanto
> > en python como en java. Los ficheros que se generan son extremadamente
> > gigantes y su creación es muy lenta (más de una semana para emitir
> > 30.000 certificados con un logotipo simple).
> >
> > Se abandonó la idea de crear estos listados vía una librería, y se
> > optó por montar una "fusión de correo" con alguna herramienta
> > ofimática (aunque, bien pensado, lo de usar LaTeX tampoco es mala idea
> > ;-).
> > _______________________________________________
> > Python-es mailing list
> > Python-es en aditel.org
> > http://listas.aditel.org/listinfo/python-es
> >
> _______________________________________________
> Python-es mailing list
> Python-es en aditel.org
> http://listas.aditel.org/listinfo/python-es
>




Más información sobre la lista de distribución Python-es