Skip to main content

JayDeBeApiArrow - High-Performance JDBC to Python DB-API Bridge

Test Status PyPI version

The JayDeBeApiArrow module allows you to connect from Python code to databases using Java JDBC. It provides a Python DB-API v2.0 to that database.

Note: This is a fork of the original JayDeBeApi project.

Key Differences in this Fork

  1. High Performance with Apache Arrow: The primary goal of this fork is to significantly improve data fetch performance. Instead of iterating through JDBC ResultSets row-by-row in Python (which has high overhead), this library uses a custom Java extension (arrow-jdbc-extension) to convert JDBC data into Apache Arrow record batches directly within the JVM. These batches are then efficiently transferred to Python.

  2. Modernization:

    • Python 3 Only: Support for Python 2 has been removed.
    • JPype Only: Support for Jython has been removed to focus on the CPython + JPype architecture.
    • Strict Typing: Enforces stricter typing for Decimal and temporal types.

It works on ordinary Python (cPython) using the JPype Java integration.

Install

You can get and install JayDeBeApiArrow with pip:

pip install JayDeBeApiArrow

Or with uv:

uv add JayDeBeApiArrow

Or install from source:

git clone https://github.com/HenryNebula/jaydebeapiArrow.git
cd jaydebeapiArrow
pip install -e .

Usage

Basically you just import the jaydebeapiarrow Python module and execute the connect method. This gives you a DB-API conform connection to the database.

The first argument to connect is the name of the Java driver class. The second argument is a string with the JDBC connection URL. Third you can optionally supply a sequence consisting of user and password or alternatively a dictionary containing arguments that are internally passed as properties to the Java DriverManager.getConnection method. See the Javadoc of DriverManager class for details.

The next parameter to connect is optional as well and specifies the jar-Files of the driver if your classpath isn't set up sufficiently yet. The classpath set in CLASSPATH environment variable will be honored.

Here is an example:

import jaydebeapiarrow
conn = jaydebeapiarrow.connect(
    "org.hsqldb.jdbcDriver",
    "jdbc:hsqldb:mem:.",
    ["SA", ""],
    "/path/to/hsqldb.jar"
)
curs = conn.cursor()
curs.execute('create table CUSTOMER'
             '("CUST_ID" INTEGER not null,'
             ' "NAME" VARCHAR(50) not null,'
             ' primary key ("CUST_ID"))')
curs.execute("insert into CUSTOMER values (?, ?)", (1, 'John'))
curs.execute("select * from CUSTOMER")
print(curs.fetchall())
# Output: [(1, 'John')]
curs.close()
conn.close()

If you're having trouble getting this work check if your JAVA_HOME environment variable is set correctly. For example:

JAVA_HOME=/usr/lib/jvm/java-8-openjdk python

An alternative way to establish connection using connection properties:

conn = jaydebeapiarrow.connect(
    "org.hsqldb.jdbcDriver",
    "jdbc:hsqldb:mem:.",
    {
        'user': "SA", 'password': "",
        'other_property': "foobar"
    },
    "/path/to/hsqldb.jar"
)

Also using the with statement might be handy:

with jaydebeapiarrow.connect(
    "org.hsqldb.jdbcDriver",
    "jdbc:hsqldb:mem:.",
    ["SA", ""],
    "/path/to/hsqldb.jar"
) as conn:
    with conn.cursor() as curs:
        curs.execute("select count(*) from CUSTOMER")
        print(curs.fetchall())
        # Output: [(1,)]

Supported Databases

In theory every database with a suitable JDBC driver should work. It is confirmed to work with the following databases:

  • SQLite
  • Hypersonic SQL (HSQLDB)
  • IBM DB2
  • IBM DB2 for mainframes
  • Oracle
  • Teradata DB
  • Netezza
  • Mimer DB
  • Microsoft SQL Server
  • MySQL
  • PostgreSQL
  • ...and many more.

Testing

Integration tests are located in test/. Tests run via pytest and cover all supported databases: SQLite (in-memory), HSQLDB, PostgreSQL, MySQL, MSSQL, Oracle, DB2, Trino, and Apache Drill.

Build JARs and download drivers

uv run bash test/build.sh                 # Build arrow-jdbc-extension and MockDriver JARs
uv run bash test/download_jdbc_drivers.sh # Download JDBC drivers

Run tests

CLASSPATH="test/jars/*:test/mock-jars/*" uv run pytest test/test_mock.py test/test_infrastructure.py -v   # Mock + infrastructure
CLASSPATH="test/jars/*" uv run pytest test/test_hsqldb.py -v                                                # HSQLDB
CLASSPATH="test/jars/*" uv run pytest test/test_sqlite.py::SqliteXerialTest -v                              # SQLite JDBC
CLASSPATH="test/jars/*" uv run pytest test/ -v --tb=short                                                  # All tests

Pytest is configured in pyproject.toml to run tests in parallel across files using pytest-xdist with --dist loadfile.

External database tests

Container-based databases are managed via Docker Compose:

# Start all databases
cd test && docker compose up -d

# Check status
cd test && docker compose ps

# Stop all databases
cd test && docker compose down

Database connection defaults (overridable via environment variables):

Database Host Port DB User Password Env prefix
PostgreSQL localhost 15432 test_db user password JY_PG_*
MySQL localhost 13306 test_db user password JY_MYSQL_*
MSSQL localhost 11433 — sa Password123! JY_MSSQL_*
Oracle localhost 11521 XEPDB1 system Password123! JY_ORACLE_*
DB2 localhost 15000 test_db db2inst1 Password123! JY_DB2_*
Trino localhost 18080 — test — JY_TRINO_*
Drill localhost 31010 — — — JY_DRILL_*

Benchmarks

This approach was inspired by Uwe Korn's work on pyarrow.jvm (Apache Drill) and Razvi Noorul's Trino benchmarks, both demonstrating 100x+ speedups by using Arrow to bypass JPype's row-by-row serialization.

Our benchmarks (local PostgreSQL, 5M rows, 4 columns) show a 23.7x speedup over plain jaydebeapi using the Native Arrow API. The difference in multiplier vs the referenced posts is due to methodology: they tested against distributed query engines (Drill, Trino) over network connections with higher per-row JDBC overhead. PostgreSQL's JDBC driver is fast at row retrieval, so the baseline is lower. The absolute Arrow throughput is comparable across all three.

The reading path uses the Arrow C Data Interface (Data.exportVectorSchemaRoot → pa.RecordBatch._import_from_c), which bypasses pyarrow.jvm entirely. This brings the Native Arrow API to within 6% of psycopg2, a native C driver.

Method 5M rows Throughput vs jaydebeapi
jaydebeapi (baseline) 180.1s 28K rows/s —
Drop-in replacement 26.5s 189K rows/s 6.8x
Native Arrow API (C Data Interface) 7.6s 658K rows/s 23.7x
Psycopg2 (native driver) 7.2s 694K rows/s 25.0x

See benchmark/ for scripts to reproduce these results.

Contributing

Please submit bugs and patches to the JayDeBeApiArrow issue tracker. All contributors will be acknowledged. Thanks!

License

JayDeBeApiArrow is released under the GNU Lesser General Public license (LGPL). See the file COPYING and COPYING.LESSER in the distribution for details.

Metadata

Release files for JayDeBeApiArrow 2.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for JayDeBeApiArrow 2.1.7
File Size Uploaded Provenance Actions
jaydebeapiarrow-2.1.7.tar.gz 9.7 MB With provenance Details for jaydebeapiarrow-2.1.7.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for JayDeBeApiArrow 2.1.7
File Interpreter ABI Platform Actions
jaydebeapiarrow-2.1.7-py3-none-any.whl Python 3 none any Details for jaydebeapiarrow-2.1.7-py3-none-any.whl

Total release size: 19.4 MB

Release files / jaydebeapiarrow-2.1.7.tar.gz

Download URL jaydebeapiarrow-2.1.7.tar.gz
Size 9.7 MB
Tags Source
SHA-256 checksum
How to use checksums
f2cd8a4e65fe6ac3085f5eccb6d6e65b7a892525f5ff8c9eccd88a2bc375db52
BLAKE2b-256 checksum
How to use checksums
b8c8a63c047e706cd9b3b7a5a2f63ddaa7b57ee9cfe10a4863cc03d4efc2b131
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / jaydebeapiarrow-2.1.7-py3-none-any.whl

Download URL jaydebeapiarrow-2.1.7-py3-none-any.whl
Size 9.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
dfc21bf9105b4d2063440a69db471ff8e30455c239473c803ea68608e6bbec61
BLAKE2b-256 checksum
How to use checksums
17f809ca4dfb8a69a10f158b150411d41945ff4a7fa5423b602887dc847a41b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for JayDeBeApiArrow 2.1.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for jaydebeapiarrow-2.1.7.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page