You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Features
Jupyter widget UI on JupyterLab - Progress bars and DataFrame views now use ipywidgets (>= 7), with prebuilt JupyterLab and classic Notebook extensions. options.display.notebook_widget defaults to None, which auto-enables widgets except on DSW and VS Code; set it to True or False to override.
Cross-process MaxStorage session descriptors - Sessions can be exported with to_descriptor() and restored in another process through descriptor=, without re-creating them on the server. Write descriptors support only WriteMode.BATCH_COMPATIBLE.
Extended Arrow IPC reads and v2 capability fields - Read sessions can use extended Arrow IPC, which delivers data and metrics together; extended_arrow_ipc_enabled reports it and open_arrow_reader handles it transparently. record_count returns -1 when unknown, and latest_txn_id supports exactly-once incremental reads.
Vector type support - Vector values are now handled by the CSV and Arrow readers and by the MaxStorage schema parser, including validation.
Opt-in write timeout - Adds the write_timeout option and WriteTimeout exception for streaming uploads. Behavior is unchanged unless the option is set.
Batch-compatible commit wait timeout - TableWriteSession.commit() accepts wait_flying_writers_timeout_seconds (1–600) to bound the server's wait for in-flight writers.
Enhancements
Small-file merge - Adds Table.merge_small_files() and Partition.merge_small_files().
Partition iteration limits and Table.is_partitioned - iterate_partitions() accepts max_items (partitions per request) and limit (total partitions), and Table.is_partitioned reports whether a table is partitioned.
Unknown instance and task statuses - Unrecognized statuses now map to UNKNOWN instead of raising ValueError.
Single-request upload for small resources - Small file resources are uploaded in one request, while non-regular files such as pipes and sockets use the chunked path.
Faster import odps - Importing odps no longer imports SQLAlchemy, IPython or the widget stack; optional dependencies load only when needed.
Widget bundles built outside cibuildwheel - Wheel builds now build the widget bundles in a separate Node 22 step, keeping JS tooling out of the manylinux images.
Bug Fixes
HTTP sessions rebuilt after a fork - RestClient and SignServerAccount now rebuild their HTTP sessions in forked children instead of reusing the parent's connections.
Error responses keep status and request id - Errors from empty or malformed responses now retain status_code, request_id and response headers.
Half-read row batches release their stream - Row batches that fail midway now close their decoder and release the HTTP connection immediately.
Resource pack loading with environment credentials - load_packages_in_subprocess now re-enters the original script, so environment credentials are inherited.
Older pyarrow compatibility - Temporal validation now works with older pyarrow and pandas versions and reports out-of-range values clearly.
Compatibility Notes
options.display.notebook_widget defaults to None - Auto-detection replaces the previous True default; set it explicitly to force widgets on or off.
odps.ui.common.html_notify removed - The notifier and ProgressUI.notify are gone, and setup/teardown magics no longer show notifications.
MaxStorage descriptor restrictions - descriptor cannot be combined with table or session_id, and to_descriptor() supports batch-compatible write sessions only.
Lazy SQLAlchemy registration - The odps dialect is registered only when SQLAlchemy is already imported; in an uninstalled source tree, import odps.sqlalchemy_odps before create_engine().
Docs
Added an FAQ on preserving exact decimal values with pandas.read_csv. Thanks @dingxin-tech
Documented lazy SQLAlchemy dialect registration and added examples for Table.is_partitioned and iterate_partitions(max_items=..., limit=...).