acesseonline / pyreportjasper

Python Reporting with JasperReports
https://pyreportjasper.readthedocs.io/en/latest/
GNU General Public License v3.0
127 stars 75 forks source link

Error - using a postgres database - NameError: Error fill report: Erro fill internal: java.lang.NullPointerException #161

Open massimiliano-della-rovere opened 9 months ago

massimiliano-della-rovere commented 9 months ago

The documentation on how to connect to a DB is COMPLETELY wrong. »This document is written and tested for pyreportjasper version 2.1.3«

Here is how I did with a bit of explanation: you need 3 different keys in the db_connection dict required by the PyReportJasper.config() method:

driver: the correct value for the PostgreSQL database is postgres; you can find the values in the pyreportjasper/db.py -> DB.get_connection() method (the dbtype string in the "if" chain)

jdbc_driver: it's the full path up to and including the jdbc directory provided with the pyreportjasper library; the easiest way to find it in your case is the following python script:

import sys
import pathlib
from pyreportjasper import PyReportJasper # <-- you probably have this line in yout code

print(str(pathlib.Path(sys.modules[PyReportJasper.__module__].__file__).parent / "libs" / "jdbc"))

jdbc_dir: the correct value for the PostgreSQL database is org.postgresql.Driver; this was the trickiest value to find out, I used the following BASh script, that can be useful if you want to use the other undocumented jdbc drivers:

# The value of the JDBC_DIR variable is the path you found with the previous python script
JDBC_DIR=/venv/py3.8.18/lib/python3.8/site-packages/pyreportjasper/libs/jdbc

basename $(strings ${JDBC_DIR}/postgresql.jar | grep -P 'Driver.class$' | sed 's#/#.#g') .class

Note the schema key is mandatory, but meaningless for PostgreSQL; set it to the very same value you are using for the database key.

Finally a recap:

self._jasper_db_parameters=JasperDBParameters(
    jdbc_driver='org.postgresql.Driver',
    jdbc_dir='/venv/py3.8.18/lib/python3.8/site-packages/pyreportjasper/libs/jdbc', 
    driver='postgres',
    host='....',
    port='....',
    username='....',
    password='....',
    schema='....',  # <-- same value you used for the database parameter
    database='....')
jadsonbr commented 9 months ago

The jdbc_dir you only need to inform in the case of PostgreSQL if you want to use a different version than the one already included with the library. In that case, you provide the path where you placed your PostgreSQL JDBC .jar file that you want to use. Otherwise, the library automatically adds the path of the JDBC that comes with it. See here.

The name of the PostgreSQL JDBC driver is easily found in its documentation. See here.

So here is a simple example of usage:

pyreportjasper = PyReportJasper()
pyreportjasper.config(
    input_file,
    output_file,
    output_formats=["pdf"],
    db_connection={
        'driver': 'postgres',
        'jdbc_driver': 'org.postgresql.Driver',
        'username': '....',
        'password': '....',
        'host': '....',
        'database': '....',
        'port': '5434',
    },
)

And yes, we do need to update and enrich our documentation with more information and examples. We appreciate any help you can provide.