mrkeyoor.com_
Tue 22 Sept 22:35 UTC
PyPIDataupdated 22 Sept 2026

pyathena review

PyAthena 3.35.4 is a Python DB API 2.0 client and SQLAlchemy dialect for Amazon Athena. It submits SQL to the remote AWS service, polls execution, and turns results into Python rows or optional Pandas, Arrow, and Polars objects. The project also has futures-based and native asyncio cursors, workgroup settings, result reuse, and AWS credential-chain support. Version 3.35.4 fixes escaper selection for DELETE and CTAS queries to prevent SQL injection under CVE-2026-65321. Our Python 3.12 install imported in 0.12 seconds with typed metadata and no audit findings, but the base environment occupied 33 MB.

Verdict

PyAthena 3.35.4 installed in 0.5 seconds as 10 packages using 33 MB, imported in 0.12 seconds, and had 0 audit findings in our sandbox. Use it when DB API, SQLAlchemy, dataframe, or async conveniences justify the client; boto3 is clearer for a couple of tightly scoped Athena calls.

We installed it

Lab card: what happened when we installed pyathenaScreenshot of pyathena documentation
Install✓ · 0.5s10 packages on disk · 33 MB
Importimport pyathena in 0.12s · pure Python · py.typed · requires Python >=3.10
Known vulns0(pip-audit)

Answers from our run

Does pyathena install cleanly?

Yes. In a fresh container with an empty cache, pip install pyathena finished in 0.5s, leaving 10 packages and 33 MB on disk. pip-audit reported no known vulnerabilities.

What does pyathena need to run?

Python >=3.10, and nothing compiled: it is pure Python. In our run import pyathena succeeded in 0.12s, and the package ships py.typed for type checkers.

pyathena or boto3: which should you use?

boto3: Choose it for a few Athena operations where the AWS API and polling state should remain explicit. PyAthena 3.35.4 installed in 0.5 seconds as 10 packages using 33 MB, imported in 0.12 seconds, and had 0 audit findings in our sandbox.

When should you not use pyathena?

The workload needs low-latency transactions. Every execute call remains a remote Athena job with queueing, scanning, billing, result storage, and polling.

API stability4/5PyAthena 3.35.4 keeps the DB API 2.0 connect, connection, cursor, execute, and fetch contract plus established awsathena SQLAlchemy drivers. Specialized cursors expose a larger moving surface around async execution, result reuse, callbacks, dataframe conversion, and complex types. The current patch changes SQL escaping for DELETE and CTAS without replacing the public call shape, but its CVE shows that parameter behavior deserves regression tests on write-capable statements.
Docs5/5The official site returned HTTP 200 and documents credentials, environment variables, standard and managed-result workgroups, parameter styles, result reuse, callbacks, cancellation, cursor variants, chunked Pandas reads, Arrow and Polars, SQLAlchemy sync and async URLs, and complex types. Examples separate the futures-based AsyncCursor from aio_connect and warn about dataframe memory. Users still need AWS documentation for IAM, S3 policy, workgroup billing, and Athena SQL semantics.
Maintenance5/5PyPI published 3.35.4 on July 31, 2026 to fix CVE-2026-65321 in DELETE and CTAS escaper selection. GitHub reports a push on August 11, 2026, 492 stars, 14 open issues and pull requests combined, and an unarchived repository. Current classifiers and dependency markers cover Python 3.10 through 3.14, and extras track recent Pandas, Arrow, Polars, and SQLAlchemy releases. The security patch and follow-up push show active ownership.
Ecosystem4/5The supplied snapshot records 5,533,025 weekly downloads, while GitHub reports 492 stars. PyAthena builds on boto3 credentials and AWS APIs, follows DB API 2.0, ships py.typed, and connects to SQLAlchemy plus optional Pandas, Arrow, Polars, and asyncio paths. That coverage fits many Python analytics stacks. It remains Athena-specific, and our base installation already used 33 MB before optional dataframe or ORM packages were added.

Use it if

  • Athena queries should fit existing Python DB API cursor code instead of a custom boto3 polling loop.
  • An application needs an Athena SQLAlchemy dialect with AWS credential-chain authentication.
  • Query results regularly move into Pandas, Arrow, or Polars and the matching optional extra is acceptable.
  • Native asyncio, future cursors, workgroup controls, cancellation, or Athena result reuse will replace substantial in-house code.
Skip it if

Setup reality

We installed PyAthena 3.35.4 in a fresh Python 3.12 Bookworm sandbox. The install completed in 0.5 seconds, left 10 packages, and used 33 MB. The pure-Python distribution reports 12 direct dependencies, requires Python 3.10 or newer, ships py.typed, and imported in 0.12 seconds. pip-audit found 0 known vulnerabilities. PyPI publishes MIT-style license text, and GitHub labels the repository MIT.

Use the normal AWS credential provider chain rather than passing keys in source. The principal needs Athena query permissions, catalog access, and permission to read or write the result location. A standard workgroup needs s3_staging_dir or AWS_ATHENA_S3_STAGING_DIR, with a bucket and region that match policy. A workgroup using Athena-managed query results can omit external S3 output; pass an explicit empty staging string if an inherited environment variable would otherwise override it.

Connection creation is lazy enough that configuration errors often appear on execute. Set region, workgroup, catalog, and schema explicitly, then run a cheap query during startup or deployment checks. The default pyformat parameter style performs client-side formatting; use paramstyle qmark for Athena execution parameters. Version 3.35.4 specifically fixes SQL escaping for DELETE and CTAS, so do not remain on 3.35.3 when those statements can include parameters.

The plain cursor blocks while Athena runs. AsyncCursor returns concurrent futures and does not follow DB API 2.0; aio_connect is the native asyncio interface. Install the pandas, arrow, polars, sqlalchemy, or aiosqlalchemy extra before importing those paths. Chunking controls local dataframe memory but does not reduce bytes scanned. Result reuse can return an earlier equivalent result inside its age window, so disable it for freshness-sensitive reads and use partitions, workgroup limits, timeouts, and cancellation to control cost.

Patterns

Execute a DB API query run-query

from pyathena import connect

with connect(
    s3_staging_dir='s3://analytics-results/pyathena/',
    region_name='us-east-1',
    work_group='analysts',
) as conn:
    with conn.cursor() as cur:
        cur.execute('SELECT current_date')
        print(cur.fetchone())

The first execute is where IAM, region, workgroup, and staging-location errors usually surface.

Select workgroup-managed result storage use-managed-results

conn = connect(
    work_group='managed-results-group',
    s3_staging_dir='',
    region_name='us-east-1',
)

An explicit empty string prevents AWS_ATHENA_S3_STAGING_DIR from forcing an external bucket onto a managed-results workgroup.

Use Athena execution parameters parameterize-query

cur = connect(
    s3_staging_dir=staging,
    region_name='us-east-1',
    paramstyle='qmark',
).cursor()
cur.execute(
    'SELECT * FROM events WHERE event_date = ? AND account_id = ?',
    ['2026-08-01', 'acct-42'],
)

qmark uses Athena execution parameters; default pyformat performs client-side formatting and follows different escaping rules.

Process rows without fetchall iterate-rows

cur.execute('SELECT id, total FROM orders')
for order_id, total in cur:
    process(order_id, total)

Iteration avoids a second full Python list, although Athena has already written the remote query result.

Address row values by column name fetch-dictionaries

from pyathena.cursor import DictCursor

cur = connect(s3_staging_dir=staging, region_name='us-east-1').cursor(DictCursor)
cur.execute('SELECT order_id, status FROM orders LIMIT 100')
for row in cur:
    print(row['order_id'], row['status'])

Alias duplicate column names explicitly because a dictionary row cannot preserve two values under the same key.

Read a bounded result into Pandas load-pandas

from pyathena.pandas.cursor import PandasCursor

cur = connect(s3_staging_dir=staging, region_name='us-east-1').cursor(PandasCursor)
df = cur.execute(
    "SELECT * FROM daily_summary WHERE day >= DATE '2026-08-01'"
).as_pandas()

Install PyAthena[pandas]. An unchunked PandasCursor can hold the entire result in memory.

Bound local dataframe memory read-pandas-chunks

cur.execute('SELECT * FROM large_events', chunksize=50_000)
for frame in cur.iter_chunks():
    write_partition(frame)

A 50,000-row chunk limits local dataframe size but does not change Athena bytes scanned or query charges.

Await a query with aio_connect run-native-async

from pyathena import aio_connect

async with await aio_connect(
    s3_staging_dir=staging,
    region_name='us-east-1',
) as conn:
    cur = conn.cursor()
    await cur.execute('SELECT 1')
    row = await cur.fetchone()

aio_connect is the native asyncio API; AsyncCursor is a separate futures-based cursor that is not DB API 2.0.

Allow a recent equivalent result reuse-result

cur.execute(
    "SELECT count(*) FROM events WHERE day = DATE '2026-08-01'",
    result_reuse_enable=True,
    result_reuse_minutes=15,
)

The 15-minute reuse window can return older data, so leave it disabled when the latest table state is required.

Build an Athena SQLAlchemy engine create-sqlalchemy-engine

from sqlalchemy import create_engine, text

engine = create_engine(
    'awsathena+rest://:@athena.us-east-1.amazonaws.com:443/default',
    connect_args={'s3_staging_dir': staging, 'work_group': 'analysts'},
)
with engine.connect() as conn:
    rows = conn.execute(text('SELECT 1')).all()

Install PyAthena[sqlalchemy] and let boto3 discover credentials instead of embedding AWS keys in the URL.

Alternatives

PackageRegistryPick it when
boto3PyPIChoose it for a few Athena operations where the AWS API and polling state should remain explicit.
awswranglerPyPIChoose it for dataframe-first workflows spanning Athena, Glue, S3, and other AWS analytics services.
pyhivePyPIChoose it for a DB API or SQLAlchemy layer aimed at Hive or Presto rather than Athena-specific controls.

More data guides

numpy · fsspec · pandas · sqlalchemy · pyarrow · lxml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.