Denodo SQLAlchemy Dialect

raw JSON →
2.0.5 verified Fri May 01 auth: no python

A SQLAlchemy dialect for Denodo, enabling SQLAlchemy ORM and Core to connect to Denodo Virtual DataPort. Current version 2.0.5, requires Python >=3.9 and SQLAlchemy >=2.0. Released as needed, with breaking changes in the major version bump from 1.x to 2.x due to SQLAlchemy 2.0 compatibility.

pip install denodo-sqlalchemy
error sqlalchemy.exc.ArgumentError: Could not determine a dialect for "denodo"
cause The dialect 'denodo' is not registered or installed improperly.
fix
Ensure 'denodo-sqlalchemy' is installed: pip install denodo-sqlalchemy. Then import it at least once before creating engine.
error jaydebeapi.JavaNotFoundError: The Java runtime could not be found.
cause JPype1 cannot locate Java installation.
fix
Install Java (JRE or JDK) and ensure JAVA_HOME environment variable is set correctly.
error RuntimeError: Class not found: com.denodo.vdb.jdbcdriver.Driver
cause Denodo JDBC driver JAR is not in CLASSPATH.
fix
Download Denodo JDBC driver JAR and add its path to CLASSPATH environment variable.
breaking denodo-sqlalchemy 2.x requires SQLAlchemy >=2.0 and drops support for SQLAlchemy 1.x.
fix Upgrade SQLAlchemy to >=2.0 and adjust code for SQLAlchemy 2.0 patterns (e.g., removed convert_unicode, future=True).
gotcha The dialect name in connection string is 'denodo' (lowercase), not 'denodosqlalchemy' or 'Denodo'.
fix Use 'denode+pyodbc?' or 'denode://...' with 'denodo' prefix (e.g., denodo://user:pass@host:9999/db).
gotcha Requires Java and a JDBC driver (Denodo's JDBC JAR) to be accessible on the CLASSPATH. Without it, jaydebeapi will raise 'JavaNotFoundError' or 'RuntimeError: Class not found'.
fix Set CLASSPATH environment variable to include the Denodo JDBC JAR, or place it in the working directory.

Connect to Denodo using SQLAlchemy engine.

from sqlalchemy import create_engine, text
import os

user = os.environ.get('DENODO_USER', '')
password = os.environ.get('DENODO_PASSWORD', '')
host = os.environ.get('DENODO_HOST', 'localhost')
database = os.environ.get('DENODO_DATABASE', 'test')

engine = create_engine(f'denodo://{user}:{password}@{host}:9999/{database}')

with engine.connect() as conn:
    result = conn.execute(text("SELECT 1"))
    print(result.fetchone())