Skip to content

[Feature request] Add read_parquet() table-valued function construct #1398

Description

@giunio-prc

Feature request

Problem

When querying DuckDB parquet files via the Python duckdb client, the path must be
interpolated into the SQL string as a literal (DuckDB resolves the schema at planning
time, so it cannot be a bind parameter). This forces f-string SQL construction, which
triggers linter rule S608 (possible SQL injection via string-based query construction).

Proposed solution

Add a read_parquet SQLAlchemy FunctionElement to duckdb_engine that:

  • Accepts the path through SQLAlchemy's API (not a raw f-string in caller code)
  • Compiles to a SQL literal with single-quote escaping in the dialect compiler
  • Supports .table_valued(...) so the rest of the query can use proper bind parameters

Before (current workaround)

con.execute(
    f"SELECT col FROM read_parquet('{tmp_path}/*.parquet') WHERE x = ?",
    [value]
)

After (proposed)

from duckdb_engine.functions import read_parquet

rp = read_parquet(str(tmp_path / "*.parquet")).table_valued("col", "x")
stmt = select(rp.c.col).where(rp.c.x == bindparam("x"))

Question

Would you accept a PR for this? Any preferences on placement (e.g. a new
duckdb_engine/functions.py) or API shape?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions