API Reference¶
This section provides detailed API documentation for SQLAlchemy JDBC/ODBC API.
Overview¶
The library is organized into three main modules:
JDBC Module (
sqlalchemy_jdbcapi.jdbc) - Native JDBC bridge implementationODBC Module (
sqlalchemy_jdbcapi.odbc) - Native ODBC connectivityDialects Module (
sqlalchemy_jdbcapi.dialects) - SQLAlchemy dialect implementations
Package Structure¶
sqlalchemy_jdbcapi/
├── jdbc/ # JDBC bridge layer (DB-API 2.0)
│ ├── connection.py # Connection class
│ ├── cursor.py # Cursor class
│ ├── exceptions.py # Exception hierarchy
│ ├── types.py # DB-API type objects
│ ├── type_converter.py # JDBC ↔ Python type conversion
│ ├── jvm.py # JVM management
│ ├── driver_manager.py # Driver management
│ └── dataframe.py # DataFrame integration
├── odbc/ # ODBC bridge layer
│ ├── connection.py # ODBC Connection implementation
│ └── exceptions.py # ODBC exceptions
└── dialects/ # SQLAlchemy dialects
├── base.py # Base dialect
├── postgresql.py # PostgreSQL dialect
├── oracle.py # Oracle dialect
├── mysql.py # MySQL/MariaDB dialects
├── mssql.py # SQL Server dialect
├── db2.py # DB2 dialect
├── oceanbase.py # OceanBase dialect
├── sqlite.py # SQLite dialect
└── odbc_*.py # ODBC dialect variants
Main Entry Point¶
SQLAlchemy JDBC API - Modern JDBC Dialect for SQLAlchemy.
This package provides a modern, type-safe SQLAlchemy dialect for JDBC connections, supporting multiple databases through a native JPype-based implementation.
Supported Databases: - PostgreSQL - Oracle Database - OceanBase (Oracle mode) - MySQL - MariaDB - Microsoft SQL Server - IBM DB2 - SQLite (via JDBC)
Features: - Modern Python 3.10+ with full type hints - Native JDBC implementation (no JayDeBeApi dependency) - DataFrame integration (pandas, polars, pyarrow) - SQLAlchemy 2.0+ compatible - Comprehensive error handling and logging - Connection pooling support
- Example usage:
>>> from sqlalchemy import create_engine >>> # PostgreSQL >>> engine = create_engine('jdbcapi+postgresql://user:pass@localhost/db') >>> # Oracle >>> engine = create_engine('jdbcapi+oracle://user:pass@localhost:1521/ORCL') >>> # MySQL >>> engine = create_engine('jdbcapi+mysql://user:pass@localhost/db')
- class sqlalchemy_jdbcapi.PostgreSQLDialect(native_inet_types=None, json_serializer=None, json_deserializer=None, **kwargs)[source]¶
Bases:
BaseJDBCDialect,PGDialectPostgreSQL dialect using JDBC driver.
Supports all PostgreSQL-specific features including: - Arrays - JSONB - UUID - Full-text search - Custom types
- Connection URL format:
jdbcapi+postgresql://user:password@host:5432/database jdbcapi+pgjdbc://user:password@host:5432/database # Alias
- do_ping(dbapi_connection)[source]¶
Check if PostgreSQL connection is alive.
Uses a simple SELECT query for efficiency.
- name: str = 'postgresql'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_boolean: bool = True¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = True¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_smallserial = True¶
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.OracleDialect(use_ansi=True, optimize_limits=False, use_binds_for_limits=None, use_nchar_for_unicode=False, exclude_tablespaces=('SYSTEM', 'SYSAUX'), enable_offset_fetch=True, **kwargs)[source]¶
Bases:
BaseJDBCDialect,OracleDialectOracle Database dialect using JDBC driver.
Supports Oracle-specific features including: - Sequences - Synonyms - Database links - Packages - Custom types
- Connection URL formats:
jdbcapi+oracle://user:password@host:1521/database jdbcapi+oracle://user:password@host:1521/SID jdbcapi+oraclejdbc://user:password@host:1521/service_name # Alias
- For TNS connections:
jdbcapi+oracle://user:password@tnsname
- colspecs: MutableMapping[Type[TypeEngine[Any]], Type[TypeEngine[Any]]] = {<class 'sqlalchemy.sql.sqltypes.Boolean'>: <class 'sqlalchemy.dialects.oracle.types._OracleBoolean'>, <class 'sqlalchemy.sql.sqltypes.Date'>: <class 'sqlalchemy.dialects.oracle.types._OracleDate'>, <class 'sqlalchemy.sql.sqltypes.DateTime'>: <class 'sqlalchemy.dialects.oracle.types.DATE'>, <class 'sqlalchemy.sql.sqltypes.Interval'>: <class 'sqlalchemy.dialects.oracle.types.INTERVAL'>}¶
A dictionary of TypeEngine classes from sqlalchemy.types mapped to subclasses that are specific to the dialect class. This dictionary is class-level only and is not accessed from the dialect instance itself.
- create_connect_args(url)[source]¶
Create connection arguments from SQLAlchemy URL.
Handles various Oracle connection formats including TNS names.
- do_ping(dbapi_connection)[source]¶
Check if Oracle connection is alive.
Uses Oracle’s dual table for efficiency.
- name: str = 'oracle'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- class sqlalchemy_jdbcapi.OceanBaseDialect(use_ansi=True, optimize_limits=False, use_binds_for_limits=None, use_nchar_for_unicode=False, exclude_tablespaces=('SYSTEM', 'SYSAUX'), enable_offset_fetch=True, **kwargs)[source]¶
Bases:
BaseJDBCDialect,OracleDialectOceanBase dialect using JDBC driver (Oracle compatibility mode).
OceanBase is a distributed database that supports both MySQL and Oracle compatibility modes. This dialect implements Oracle mode.
- Connection URL format:
jdbcapi+oceanbase://user@tenant#cluster:password@host:2881/database jdbcapi+oceanbasejdbc://user:password@host:2881/database # Alias
Note: OceanBase uses a special user format: username@tenant#cluster
- colspecs: MutableMapping[Type[TypeEngine[Any]], Type[TypeEngine[Any]]] = {<class 'sqlalchemy.sql.sqltypes.Boolean'>: <class 'sqlalchemy.dialects.oracle.types._OracleBoolean'>, <class 'sqlalchemy.sql.sqltypes.Date'>: <class 'sqlalchemy.dialects.oracle.types._OracleDate'>, <class 'sqlalchemy.sql.sqltypes.DateTime'>: <class 'sqlalchemy.dialects.oracle.types.DATE'>, <class 'sqlalchemy.sql.sqltypes.Interval'>: <class 'sqlalchemy.dialects.oracle.types.INTERVAL'>, <class 'sqlalchemy.sql.sqltypes.TIMESTAMP'>: <class 'sqlalchemy_jdbcapi.dialects.oceanbase.ObTimestamp'>}¶
A dictionary of TypeEngine classes from sqlalchemy.types mapped to subclasses that are specific to the dialect class. This dictionary is class-level only and is not accessed from the dialect instance itself.
- create_connect_args(url)[source]¶
Create connection arguments for OceanBase.
Handles special OceanBase user format and connection properties.
- do_rollback(dbapi_connection)[source]¶
Perform rollback on OceanBase connection.
OceanBase sometimes has issues with rollback, this provides error handling.
- name: str = 'oceanbase'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_decimal: bool = True¶
indicates if Decimal objects are handled and returned for precision numeric types, or if floats are returned
- supports_sane_multi_rowcount: bool = False¶
Indicate whether the dialect properly implements rowcount for
UPDATEandDELETEstatements when executed via executemany.
- supports_sane_rowcount: bool = False¶
Indicate whether the dialect properly implements rowcount for
UPDATEandDELETEstatements.
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- supports_unicode_binds = True¶
- class sqlalchemy_jdbcapi.MySQLDialect(json_serializer=None, json_deserializer=None, is_mariadb=None, **kwargs)[source]¶
Bases:
BaseJDBCDialect,MySQLDialectMySQL dialect using JDBC driver.
Supports MySQL-specific features including: - AUTO_INCREMENT - Full-text indexes - JSON columns (MySQL 5.7+) - Spatial types
- Connection URL format:
jdbcapi+mysql://user:password@host:3306/database
- name: str = 'mysql'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = True¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.MariaDBDialect(json_serializer=None, json_deserializer=None, is_mariadb=None, **kwargs)[source]¶
Bases:
MySQLDialectMariaDB dialect using JDBC driver.
MariaDB is a MySQL fork with additional features. This dialect extends MySQL with MariaDB-specific capabilities.
- Connection URL format:
jdbcapi+mariadb://user:password@host:3306/database
- class sqlalchemy_jdbcapi.MSSQLDialect(query_timeout=None, use_scope_identity=True, schema_name='dbo', deprecate_large_types=None, supports_comments=None, json_serializer=None, json_deserializer=None, legacy_schema_aliasing=None, ignore_no_transaction_on_rollback=False, **opts)[source]¶
Bases:
BaseJDBCDialect,MSDialectMicrosoft SQL Server dialect using JDBC driver.
Supports SQL Server-specific features including: - T-SQL extensions - TOP clause - OUTPUT clause - Common Table Expressions (CTEs) - Window functions - JSON support (SQL Server 2016+)
- Connection URL formats:
jdbcapi+mssql://user:password@host:1433/database jdbcapi+sqlserver://user:password@host:1433/database # Alias
- name: str = 'mssql'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- class sqlalchemy_jdbcapi.DB2Dialect[source]¶
Bases:
BaseJDBCDialect,DialectIBM DB2 dialect using JDBC driver.
Supports DB2-specific features including: - Sequences - Identity columns - Generated columns - Temporal tables (DB2 10+) - JSON support (DB2 11+)
- Connection URL format:
jdbcapi+db2://user:password@host:50000/database
- name: str = 'db2'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- class sqlalchemy_jdbcapi.SQLiteDialect(native_datetime=False, json_serializer=None, json_deserializer=None, _json_serializer=None, _json_deserializer=None, **kwargs)[source]¶
Bases:
BaseJDBCDialect,SQLiteDialectSQLite dialect using JDBC driver.
Note: For production use, the native sqlite3 dialect is recommended. This JDBC dialect is primarily useful for: - Testing JDBC infrastructure - Java application integration - Environments where native sqlite3 is not available
- Connection URL format:
jdbcapi+sqlite:///path/to/database.db jdbcapi+sqlite:///:memory: # In-memory database
- create_connect_args(url)[source]¶
Create connection arguments for SQLite.
Handles file paths and in-memory databases.
- classmethod import_dbapi()[source]¶
Import JDBC module.
SQLAlchemy’s SQLite dialect expects sqlite_version_info attribute, so we add it as a wrapper.
- name: str = 'sqlite'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_decimal: bool = False¶
indicates if Decimal objects are handled and returned for precision numeric types, or if floats are returned
- class sqlalchemy_jdbcapi.GBase8sDialect[source]¶
Bases:
BaseJDBCDialect,DialectGBase 8s dialect using JDBC driver.
GBase 8s is an enterprise-grade database system from South Technology Group, based on Informix architecture with PostgreSQL-compatible features.
Supports GBase 8s-specific features including: - Sequences - Identity columns - Stored procedures - Full-text search - JSON support (GBase 8s 8.8+) - Spatial data types
- Connection URL format:
jdbcapi+gbase8s://user:password@host:9088/database jdbcapi+gbase://user:password@host:9088/database (alias)
- name: str = 'gbase8s'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_multivalues_insert: bool = True¶
Target database supports INSERT…VALUES with multiple value sets, i.e. INSERT INTO table (cols) VALUES (…), (…), (…), …
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = False¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.GBaseDialect[source]¶
Bases:
GBase8sDialectAlias for GBase8sDialect for convenience.
- class sqlalchemy_jdbcapi.IBMiSeriesDialect[source]¶
Bases:
BaseJDBCDialect,DialectIBM iSeries (AS/400) dialect using JDBC driver.
IBM iSeries (IBM i) is an integrated operating system for IBM Power Systems with integrated DB2 for i database. This dialect uses the IBM Toolbox for Java (JTOpen) JDBC driver to connect to iSeries systems.
Supports iSeries-specific features including: - Record-level locking - Commitment control - SQL schemas (libraries) - Journaling - System naming convention - DB2 for i SQL features
- Connection URL format:
jdbcapi+iseries://user:password@host/library jdbcapi+as400://user:password@host/library (alias) jdbcapi+ibmi://user:password@host/library (alias)
- Special connection properties:
naming: ‘sql’ (default) or ‘system’ (for *LIBL resolution)
libraries: comma-separated list of libraries to add to library list
date format: iso, usa, eur, jis, mdy, dmy, ymd, jul
- classmethod create_connect_args(url)[source]¶
Create connection arguments from URL.
IBM iSeries JDBC URLs have special requirements: - The “database” is actually the default library (schema) - Additional properties for naming convention and library lists
- default_schema_name: str | None = 'QGPL'¶
the name of the default schema. This value is only available for supporting dialects, and is typically populated during the initial connection to the database.
- has_table(connection, table_name, schema=None)[source]¶
Check if a table exists in the specified library/schema.
- name: str = 'iseries'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_empty_insert: bool = False¶
dialect supports INSERT () VALUES (), i.e. a plain INSERT with no columns in it.
This is not usually supported; an “empty” insert is typically suited using either “INSERT..DEFAULT VALUES” or “INSERT … (col) VALUES (DEFAULT)”.
- supports_multivalues_insert: bool = True¶
Target database supports INSERT…VALUES with multiple value sets, i.e. INSERT INTO table (cols) VALUES (…), (…), (…), …
- supports_native_boolean: bool = False¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = False¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.IBMiDialect[source]¶
Bases:
IBMiSeriesDialectAlias for IBMiSeriesDialect (modern name).
- class sqlalchemy_jdbcapi.AS400Dialect[source]¶
Bases:
IBMiSeriesDialectAlias for IBMiSeriesDialect (legacy name).
- class sqlalchemy_jdbcapi.AccessDialect[source]¶
Bases:
BaseJDBCDialect,DialectMicrosoft Access dialect using UCanAccess JDBC driver.
UCanAccess is an open-source Java JDBC driver that reads and writes Microsoft Access databases (.mdb and .accdb files) without requiring Microsoft Office or ODBC drivers.
Limitations: - No stored procedures support (Access macros not supported) - Limited transaction support - No sequences (uses AutoNumber/COUNTER) - Limited SQL syntax compared to full SQL databases - Single-user file locking considerations
Supports Access-specific features including: - AutoNumber (COUNTER) columns - Memo fields (LONGCHAR) - OLE objects - Hyperlinks - Currency type - Yes/No (Boolean) type
- Connection URL format:
jdbcapi+access:///path/to/database.accdb jdbcapi+msaccess:///path/to/database.mdb (alias)
- Special connection properties:
memory: true to open database in memory mode
newdatabaseversion: V2000, V2003, V2007, V2010 (for creating new DB)
encrypt: true to encrypt database
jackcessopener: custom opener class
- classmethod create_connect_args(url)[source]¶
Create connection arguments from URL.
Access uses file paths instead of host/port.
URL formats supported: - jdbcapi+access:///path/to/database.accdb (Unix absolute path) - jdbcapi+access:///C:/path/to/database.accdb (Windows absolute path) - jdbcapi+access://C:/path/to/database.accdb (Windows drive letter) - jdbcapi+access:////server/share/database.accdb (UNC path)
- get_columns(connection, table_name, schema=None, **kwargs)[source]¶
Get column information for a table.
- name: str = 'access'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- postfetch_lastrowid = True¶
- supports_empty_insert: bool = False¶
dialect supports INSERT () VALUES (), i.e. a plain INSERT with no columns in it.
This is not usually supported; an “empty” insert is typically suited using either “INSERT..DEFAULT VALUES” or “INSERT … (col) VALUES (DEFAULT)”.
- supports_multivalues_insert: bool = False¶
Target database supports INSERT…VALUES with multiple value sets, i.e. INSERT INTO table (cols) VALUES (…), (…), (…), …
- supports_native_boolean: bool = True¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = False¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_sane_multi_rowcount: bool = False¶
Indicate whether the dialect properly implements rowcount for
UPDATEandDELETEstatements when executed via executemany.
- supports_sane_rowcount: bool = False¶
Indicate whether the dialect properly implements rowcount for
UPDATEandDELETEstatements.
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.MSAccessDialect[source]¶
Bases:
AccessDialectAlias for AccessDialect.
- class sqlalchemy_jdbcapi.AvaticaDialect[source]¶
Bases:
BaseJDBCDialect,DialectApache Avatica dialect using JDBC driver.
Apache Avatica is a framework for building database drivers. It provides a wire protocol and client-side drivers that can communicate with any Avatica-compliant server, including:
Apache Phoenix (HBase SQL layer)
Apache Drill (schema-free SQL query engine)
Apache Calcite (SQL query planning and optimization)
Supports Avatica-specific features including: - HTTP/HTTPS transport - Protobuf or JSON serialization - Authentication (Basic, SPNEGO/Kerberos, Digest) - Custom avatica properties
- Connection URL format:
jdbcapi+avatica://host:8765/?serialization=protobuf jdbcapi+phoenix://host:8765/?schema=myschema (Phoenix alias) jdbcapi+calcite://host:8765/ (Calcite alias)
- Special connection properties:
serialization: PROTOBUF or JSON
authentication: BASIC, DIGEST, SPNEGO
avatica_user: Avatica authentication user
avatica_password: Avatica authentication password
truststore: Path to truststore for HTTPS
truststore_password: Truststore password
- classmethod create_connect_args(url)[source]¶
Create connection arguments from URL.
Avatica URLs are complex and support various configurations.
- name: str = 'avatica'¶
identifying name for the dialect from a DBAPI-neutral point of view (i.e. ‘sqlite’)
- supports_multivalues_insert: bool = True¶
Target database supports INSERT…VALUES with multiple value sets, i.e. INSERT INTO table (cols) VALUES (…), (…), (…), …
- supports_native_boolean: bool = True¶
Indicates if the dialect supports a native boolean construct. This will prevent
_types.Booleanfrom generating a CHECK constraint when that type is used.
- supports_native_enum: bool = False¶
Indicates if the dialect supports a native ENUM construct. This will prevent
_types.Enumfrom generating a CHECK constraint when that type is used in “native” mode.
- supports_server_side_cursors: generic_fn_descriptor[bool] | bool = False¶
indicates if the dialect supports server side cursors
- supports_statement_cache: bool = True¶
indicates if this dialect supports caching.
All dialects that are compatible with statement caching should set this flag to True directly on each dialect class and subclass that supports it. SQLAlchemy tests that this flag is locally present on each dialect subclass before it will use statement caching. This is to provide safety for legacy or new dialects that are not yet fully tested to be compliant with SQL statement caching.
Added in version 1.4.5.
See also
- class sqlalchemy_jdbcapi.PhoenixDialect[source]¶
Bases:
AvaticaDialectApache Phoenix dialect (HBase SQL layer).
Phoenix provides SQL access to HBase with full ACID transaction support.
- Connection URL format:
jdbcapi+phoenix://zookeeper-host:2181/?schema=myschema
- class sqlalchemy_jdbcapi.CalciteDialect[source]¶
Bases:
AvaticaDialectApache Calcite dialect.
Calcite is a foundational framework for building databases and data management systems.
- Connection URL format:
jdbcapi+calcite://host:8765/?model=/path/to/model.json