pyexasol Exasol Python Driver

raw JSON →
2.1.0 verified Tue May 12 auth: no python install: verified

pyexasol is the officially supported Python connector for Exasol, designed for high-performance data handling with low overhead, fast HTTP transport, and compression. It provides an API for parallel data stream processing, offering significant performance improvements over ODBC/JDBC solutions, especially with `pandas`, `parquet`, and `polars`. The library is actively maintained with a regular release cadence, often seeing monthly or bi-monthly updates.

pip install pyexasol
error ModuleNotFoundError: No module named 'pyexasol'
cause The 'pyexasol' package is not installed in the Python environment where the code is being executed.
fix
pip install pyexasol
error ExaConnectionFailedError: Could not connect to Exasol
cause The client machine cannot establish a network connection to the Exasol database, often due to an incorrect DSN (host or port), firewall restrictions, or the database being offline.
fix
Verify the DSN (host and port), check network connectivity (e.g., using 'telnet <host> 8563'), ensure the Exasol database is running, and confirm the client's IP address is allow-listed if connecting to Exasol SaaS.
error OperationalError: database error [08004] Connection exception - Client connection must be encrypted.
cause The Exasol database is configured to only accept encrypted connections, but the pyexasol client is attempting to connect without encryption enabled.
fix
Explicitly set encryption=True in the pyexasol.connect() call: pyexasol.connect(dsn='...', user='...', password='...', encryption=True).
error ssl.SSLEOFError: EOF occurred in violation of protocol
cause An issue with the SSL/TLS handshake between the client and the Exasol server, often due to an outdated OpenSSL version, invalid certificates, or network intermediaries interfering with the SSL connection.
fix
Update OpenSSL on the client machine, ensure proper TLS/SSL certificate setup (e.g., using trusted CA certificates or fingerprint verification), or, for testing purposes, disable certificate verification (though this is not recommended for production).
error TypeError: cannot serialize '_io.FileIO' object
cause This error typically occurred on Windows systems in older pyexasol versions (before 0.3.23) when using `export_to_pandas`, due to Python's `multiprocessing` module's limitations in serializing file-like objects across processes.
fix
Upgrade the pyexasol package to version 0.3.23 or higher using pip install --upgrade pyexasol.
breaking Python 3.9 support was dropped in PyExasol v2.0.0. Projects using Python 3.9 or older must upgrade their Python version to >=3.10 to use PyExasol v2.0.0 or later.
fix Upgrade your Python environment to 3.10 or newer.
breaking The `export_params['with_column_names']` parameter for export functions (e.g., `export_to_pandas`) now strictly requires a boolean value. Prior to v2.0.0, its mere presence would be interpreted as `True` regardless of the assigned value.
fix Ensure `export_params['with_column_names']` is explicitly set to `True` or `False`.
breaking From PyExasol v1.0.0, strict certificate verification became the default behavior for `pyexasol.connect()` and `ExaConnection`. This changes the default `websocket_sslopt=None` from effectively `{'cert_reqs': ssl.CERT_NONE}` to `{'cert_reqs': ssl.CERT_REQUIRED}`, potentially causing `SSL: CERTIFICATE_VERIFY_FAILED` errors for users not explicitly configuring SSL options. Version 1.0.1 introduced a partial mitigation for fingerprint users.
fix For production, provide valid SSL certificates via `websocket_sslopt={'ca_certs': 'path/to/cert.pem'}` or use server fingerprints. For development/testing on untrusted networks, consider `websocket_sslopt={'check_hostname': False, 'verify_mode': 0}` (use with caution and never in production).
gotcha When using `export_to_parquet`, the destination directory (dst) by default must be empty or not exist. If it exists and contains files, an exception may be raised unless `callback_params['existing_data_behavior']` is set to 'overwrite_or_ignore' or 'delete_matching'.
fix Ensure the `dst` directory is empty, doesn't exist, or explicitly set `callback_params={'existing_data_behavior': 'overwrite_or_ignore'}` (or 'delete_matching') when calling `export_to_parquet`.
gotcha When exporting data to pandas using `export_to_pandas`, data types might not be perfectly preserved due to differences in Exasol and pandas/NumPy type systems (e.g., Exasol's exact decimals or large integers may map to floats or objects in pandas, potentially losing precision). The underlying mechanism uses CSV export/import.
fix For critical data type preservation, inspect column types after import. Use `callback_params` to pass custom `dtype` arguments to `pandas.read_csv` if necessary, or use `stmt.fetchall()` and manually construct a DataFrame with explicit dtypes.
gotcha PyExasol v2.1.0 improved error reporting for `import_from_callback` and `export_to_callback` by wrapping exceptions from various internal threads. Earlier versions might have provided less clear error messages during data transfer failures, making debugging harder.
fix Upgrade to v2.1.0 or later for enhanced error diagnostics in import/export operations involving callbacks. For older versions, examine logs from HTTP and SQL threads for more context.
pip install pyexasol[pandas,pyarrow,polars,orjson]
python os / libc variant status wheel install import disk
3.10 alpine (musl) pyexasol wheel - 0.17s 35.9M
3.10 alpine (musl) pyexasol - - 0.17s 34.9M
3.10 alpine (musl) pandas,pyarrow,polars,orjson wheel - 0.17s 567.8M
3.10 alpine (musl) pandas,pyarrow,polars,orjson - - 0.17s 528.2M
3.10 slim (glibc) pyexasol wheel 2.7s 0.12s 36M
3.10 slim (glibc) pyexasol - - 0.11s 35M
3.10 slim (glibc) pandas,pyarrow,polars,orjson wheel 12.9s 0.11s 535M
3.10 slim (glibc) pandas,pyarrow,polars,orjson - - 0.11s 497M
3.11 alpine (musl) pyexasol wheel - 0.28s 38.3M
3.11 alpine (musl) pyexasol - - 0.31s 37.2M
3.11 alpine (musl) pandas,pyarrow,polars,orjson wheel - 0.27s 592.9M
3.11 alpine (musl) pandas,pyarrow,polars,orjson - - 0.32s 553.3M
3.11 slim (glibc) pyexasol wheel 2.4s 0.25s 39M
3.11 slim (glibc) pyexasol - - 0.23s 38M
3.11 slim (glibc) pandas,pyarrow,polars,orjson wheel 12.6s 0.25s 560M
3.11 slim (glibc) pandas,pyarrow,polars,orjson - - 0.24s 521M
3.12 alpine (musl) pyexasol wheel - 0.22s 30.0M
3.12 alpine (musl) pyexasol - - 0.24s 28.9M
3.12 alpine (musl) pandas,pyarrow,polars,orjson wheel - 0.23s 577.0M
3.12 alpine (musl) pandas,pyarrow,polars,orjson - - 0.23s 537.4M
3.12 slim (glibc) pyexasol wheel 2.2s 0.23s 30M
3.12 slim (glibc) pyexasol - - 0.23s 29M
3.12 slim (glibc) pandas,pyarrow,polars,orjson wheel 12.0s 0.24s 544M
3.12 slim (glibc) pandas,pyarrow,polars,orjson - - 0.24s 506M
3.13 alpine (musl) pyexasol wheel - 0.23s 29.7M
3.13 alpine (musl) pyexasol - - 0.22s 28.6M
3.13 alpine (musl) pandas,pyarrow,polars,orjson wheel - 0.22s 575.8M
3.13 alpine (musl) pandas,pyarrow,polars,orjson - - 0.23s 536.1M
3.13 slim (glibc) pyexasol wheel 2.2s 0.22s 30M
3.13 slim (glibc) pyexasol - - 0.22s 29M
3.13 slim (glibc) pandas,pyarrow,polars,orjson wheel 12.3s 0.23s 543M
3.13 slim (glibc) pandas,pyarrow,polars,orjson - - 0.22s 504M
3.9 alpine (musl) pyexasol wheel - 0.13s 37.6M
3.9 alpine (musl) pyexasol - - 0.15s 36.3M
3.9 alpine (musl) pandas,pyarrow,polars,orjson build_error - - - -
3.9 alpine (musl) pandas,pyarrow,polars,orjson - - - -
3.9 slim (glibc) pyexasol wheel 3.4s 0.12s 38M
3.9 slim (glibc) pyexasol - - 0.13s 37M
3.9 slim (glibc) pandas,pyarrow,polars,orjson wheel 14.8s 0.11s 471M
3.9 slim (glibc) pandas,pyarrow,polars,orjson - - 0.12s 470M

This quickstart demonstrates how to establish a connection to an Exasol database, execute DDL and DML statements, and fetch results. It highlights the use of `ExaConnection` and basic SQL operations. For local testing without valid SSL certificates, you might need to adjust `websocket_sslopt` as noted in the code comments. Credentials should ideally be managed via environment variables or a secure configuration.

import os
from pyexasol import ExaConnection

# Replace with your Exasol connection details or environment variables
EXASOL_HOST = os.environ.get('EXASOL_HOST', '127.0.0.1')
EXASOL_PORT = os.environ.get('EXASOL_PORT', '8563')
EXASOL_USER = os.environ.get('EXASOL_USER', 'sys')
EXASOL_PASSWORD = os.environ.get('EXASOL_PASSWORD', 'exasol')

try:
    # Connect to the Exasol database
    # For production, ensure proper SSL options and fingerprint are used
    # For local/testing without certs, add: websocket_sslopt={'check_hostname': False, 'verify_mode': 0}
    # See warnings for v1.0.0 regarding strict certificate verification defaults.
    con = ExaConnection(
        dsn=f"{EXASOL_HOST}:{EXASOL_PORT}",
        user=EXASOL_USER,
        password=EXASOL_PASSWORD
    )
    print("Successfully connected to Exasol.")

    # Execute a DDL statement
    con.execute("CREATE SCHEMA IF NOT EXISTS MY_SCHEMA")
    con.execute("OPEN SCHEMA MY_SCHEMA")

    # Execute a DML statement
    con.execute("CREATE OR REPLACE TABLE my_table (id INT, name VARCHAR(100))")
    con.execute("INSERT INTO my_table VALUES (1, 'Alice'), (2, 'Bob')")

    # Fetch data
    stmt = con.execute("SELECT * FROM my_table ORDER BY id")
    results = stmt.fetchall()
    print("Fetched results:", results)

    # Fetch data into a pandas DataFrame (requires `pyexasol[pandas]`)
    # import pandas as pd
    # df = con.export_to_pandas("SELECT * FROM my_table")
    # print("Fetched into DataFrame:\n", df)

except Exception as e:
    print(f"An error occurred: {e}")
finally:
    if 'con' in locals() and con.is_connected():
        con.close()
        print("Connection closed.")