Skip to content

[Feature Request]: Add DataFrame and Arrow interoperability to the Python SDK #30049

Closed
2 of 2 issues completed

Description

@dengn

Is there an existing issue for the same feature request?

Is your feature request related to a problem?

DataFrame/Arrow producers need a batch upload path instead of building row INSERTs. Analysis clients also need to consume large query results incrementally rather than materializing every MySQL row before constructing an Arrow table. Both paths need explicit type, transaction and cleanup guarantees.

Describe the feature you'd like

Add optional synchronous upload_dataframe, upload_arrow, and analytics.query APIs.

Requirements:

  1. Accept pandas/Polars DataFrames and Arrow Table, RecordBatch and RecordBatchReader inputs.
  2. Convert supported scalar types with checked precision, nullability and UTC timestamp handling; reject unsupported nested mappings.
  3. Create a table or append atomically using native Arrow IPC LOAD through a bounded, shared staging path.
  4. Keep strict SQL mode and TN primary-key checks active through COMMIT; restore session settings afterward.
  5. Report unknown COMMIT outcomes separately from acknowledged commits followed by cleanup failures. Never automatically retry uncertain writes.
  6. Stream query results as Arrow RecordBatches using an actual unbuffered cursor; derive types from protocol metadata for empty/all-NULL results.
  7. Bound row-batch size and provide socket inactivity timeouts, checked result casts, early-close cleanup and connection-pool reuse.
  8. Preserve the core SDK's optional-dependency behavior and existing APIs.

Describe implementation you've considered

Input: normalize Arrow batches, write an owned IPC file, issue native non-LOCAL LOAD DATA, then remove the staging file. Output: consume PyMySQL SSCursor rows in bounded batches and convert them to Arrow. Shared transaction/type helpers are also used by file exploration.

Acceptance scope is SDK interoperability over existing server interfaces. Arrow Flight, zero-copy MySQL transport, client-local upload without a shared path, asynchronous APIs and server-side query cancellation are future work.

Acceptance criteria

  • Scalar edge cases round-trip accurately, including uint64 endpoints, Decimal128 precision 38, binary/Unicode, float special values and timezone-aware timestamps.
  • Upload errors, late duplicates and concurrent primary-key conflicts do not partially commit.
  • Dropping the COMMIT success reply reports committed=None; postcommit cleanup errors report the acknowledged state.
  • Early-close, conversion and network failures release connections and retain reusable pool capacity.
  • Million-row constrained-memory streaming, fault injection and crash/restart tests have inspectable results.
  • Design, error-outcome documentation and reproducible tests accompany the implementation.

Documentation, Adoption, Use Case, Migration Strategy

client.analytics.upload_dataframe('features', df, staging_dir='/shared/staging')
with client.analytics.query('SELECT * FROM features', batch_size=4096) as batches:
    for batch in batches:
        consume(batch)

Install the optional analytics extra and the relevant DataFrame library. Native Arrow LOAD must be available on the server; this implementation was validated on a current source build, not certified against the released 4.2.5 binary.

Additional information

Existing buffered query APIs remain available. to_arrow() deliberately materializes the remaining result; iteration provides bounded row batches. A single very large cell can still dominate memory. Unknown commit outcomes require application reconciliation, and SIGKILL can leave caller-owned artifacts for explicit recovery.

Sub-features

Implementation PR

#30054 — draft implementation for design review, with the four sub-feature design documents, executable tests and recorded local evidence.

The parent feature remains open for acceptance; the PR closes its implementation sub-features on merge.

Activity

  1. added a commit that references this issue on Oct 30, 2026
    bbfe556
  2. XuPeng-SH commented on Oct 30, 2026

    @XuPeng-SH
    Contributor

    QA handoff for merged #31774 (main bbfe55669a1440424914d45a283a1d0e36f722fa): please verify the public SDK contract and failure/recovery controls for Add DataFrame and Arrow interoperability to the Python SDK. This isolated QA run inspected the issue and source but did not run functional tests or a live MatrixOne service at this SHA because the existing resource guard left insufficient headroom. Author-reported PR validation is separate evidence, not a result of this QA run.

  3. Ariznawlll commented on Oct 30, 2026

    @Ariznawlll
    Collaborator

    测试补充

    SDK:官方 main d39d8a40343ccd40bf665036388df7a40ee867f8,版本 0.1.16。真实服务使用 #31774 CI 构建,服务端 SHA db8b7b096aa67aa5922d8aef78c78b68baada983,并非该 SDK main SHA 的完整服务端二进制。

    • 覆盖 DataFrame/Arrow 上传、checked cast、NULL/类型、受限内存流式读取、连接清理和事务失败原子性;百万行流式读取在额外 128 MiB 地址空间条件下 3/3 返回 1,000,000 行,ID 求和 499999500000。该校验不等于全部 payload 的逐字节校验。
    • Python 3.9 / Arrow 18.0、Python 3.10 / Arrow 18.1 两组 Analytics 各 307/307 通过、无跳过;每组含 206 项真实服务和 101 项离线或模型检查。129 原生 Linux 同机双 CN 的主键冲突、网络故障、异步 read/load/commit 超时共 12 场景各 10 轮,120/120 通过。
    • 资源边界:129 原生 8 线程、30 秒预热加 300 秒测量完成 11,900 次操作,errors=0、连接借用/Arrow 活跃内存/pinned bytes 和自有表残留为 0,FD 峰值 13;RSS 从约 303 MiB 增至峰值 557 MiB,超过原脚本的 64 MiB 增长门槛。随后同负载 SDK 和直接 PyMySQL 各 2,640 次对照中,活跃分配稳定约 26–27 MiB,回收分配器空闲块后 RSS 回到约 140 MiB 起点;未确认持续资源泄漏。原始门槛结果仍保留,不能称原压力脚本通过;原文包含该门槛的 [Subtask]: Design and implement file-relation ownership, strict import and recovery semantics #30051 仍开放,继续跟踪。

    后续跟踪与边界

    按功能收尾处理关闭本 issue;上述仍开放的独立问题及未通过的测试门槛保持原状态,继续按关联 issue 跟踪。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions