dataframely 2.5.1__tar.gz → 2.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/build.yml +5 -5
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/chore.yml +1 -1
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/ci.yml +10 -5
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/copilot-setup-steps.yml +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/nightly.yml +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/workflows/scorecard.yml +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/.pre-commit-config.yaml +8 -1
- {dataframely-2.5.1 → dataframely-2.7.0}/Cargo.lock +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/PKG-INFO +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_compat.py +21 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/__init__.py +2 -3
- dataframely-2.7.0/dataframely/_storage/_fsspec.py +18 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/parquet.py +9 -11
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/collection/collection.py +2 -3
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/decimal.py +13 -4
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/filter_result.py +9 -4
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/schema.py +10 -8
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/storage.py +2 -13
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/faq.md +9 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/pixi.lock +8708 -6276
- {dataframely-2.5.1 → dataframely-2.7.0}/pixi.toml +35 -8
- {dataframely-2.5.1 → dataframely-2.7.0}/pyproject.toml +2 -2
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_storage.py +44 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_decimal.py +28 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/failure_info/test_storage.py +32 -4
- dataframely-2.7.0/tests/schema/test_read_write_parquet.py +61 -0
- dataframely-2.7.0/tests/storage/test_fsspec.py +26 -0
- dataframely-2.5.1/tests/schema/test_read_write_parquet.py +0 -27
- {dataframely-2.5.1 → dataframely-2.7.0}/.copier-answers.yml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.envrc +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.gitattributes +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/CODEOWNERS +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/copilot-instructions.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/dependabot.yml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/instructions/tests.instructions.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.github/release-drafter.yml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.gitignore +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.prettierignore +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.prettierrc +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/.readthedocs.yml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/Cargo.toml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/LICENSE +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/README.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/SECURITY.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_base_schema.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_deprecation.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_filter.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_match_to_schema.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_native.pyi +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_plugin.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_polars.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_pydantic.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_rule.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_serialization.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/_exc.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/constants.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_storage/delta.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/_typing.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/collection/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/collection/_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/collection/filter_result.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/_mixins.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/_registry.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/_utils.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/any.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/array.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/binary.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/bool.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/categorical.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/datetime.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/enum.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/float.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/integer.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/list.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/object.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/string.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/columns/struct.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/config.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/exc.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/functional.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/py.typed +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/random.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/const.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/factory.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/mask.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/dataframely/testing/rules.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docker-compose.yml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_static/custom.css +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_static/favicon.ico +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_templates/autosummary/class.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_templates/autosummary/method.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_templates/classes/column.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_templates/classes/error.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/_templates/classes/filter_result.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/generation.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/io.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/metadata.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/operations.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/collection/validation.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/columns/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/errors/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/filter_result/failure_info.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/filter_result/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/misc/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/conversion.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/generation.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/index.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/io.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/metadata.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/api/schema/validation.rst +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/conf.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/css/custom.css +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/development.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/examples/index.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/examples/real-world.ipynb +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/column-metadata.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/data-generation.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/index.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/lazy-validation.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/primary-keys.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/serialization.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/features/sql-generation.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/index.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/migration/index.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/migration/v1-v2.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/guides/quickstart.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/docs/index.md +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/rust-toolchain.toml +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/lib.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/polars_plugin/mod.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/polars_plugin/rule_failure.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/polars_plugin/utils.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/polars_plugin/validation_error.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/regex/errdefs.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/regex/mod.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/src/regex/repr.rs +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/benches/conftest.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/benches/test_collection.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/benches/test_failure.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/benches/test_schema.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_cast.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_collection_future_annotations.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_create_empty.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_filter_one_to_n.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_filter_validate.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_ignore_in_filter.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_implementation.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_join.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_matches.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_optional_members.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_propagate_row_failures.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_repr.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_sample.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_serialization.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/collection/test_validate_input.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_any.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_array.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_binary.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_datetime.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_enum.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_float.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_integer.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_list.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_object.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_string.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/column_types/test_struct.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_alias.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_check.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_default_dtypes.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_matches.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_metadata.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_polars_schema.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_pyarrow.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_rules.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_sample.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_sqlalchemy_columns.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_str.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/columns/test_utils.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/conftest.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/core_validation/__init__.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/core_validation/test_match_to_schema.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/core_validation/test_rule_evaluation.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/functional/test_concat.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/functional/test_relationships.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_base.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_cast.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_create_empty.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_create_empty_if_none.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_filter.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_inheritance.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_matches.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_repr.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_rule_implementation.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_sample.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_serialization.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_storage.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/schema/test_validate.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/storage/test_delta.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_compat.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_config.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_deprecation.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_factory.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_native_regex.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_pydantic.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_random.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_serialization.py +0 -0
- {dataframely-2.5.1 → dataframely-2.7.0}/tests/test_typing.py +0 -0
|
@@ -13,11 +13,11 @@ jobs:
|
|
|
13
13
|
permissions:
|
|
14
14
|
contents: read
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
17
17
|
with:
|
|
18
18
|
fetch-depth: 0
|
|
19
19
|
- name: Set up pixi
|
|
20
|
-
uses: prefix-dev/setup-pixi@
|
|
20
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
21
21
|
with:
|
|
22
22
|
environments: build
|
|
23
23
|
- name: Set version
|
|
@@ -48,16 +48,16 @@ jobs:
|
|
|
48
48
|
- target-platform: win-64
|
|
49
49
|
os: windows-latest
|
|
50
50
|
steps:
|
|
51
|
-
- uses: actions/checkout@
|
|
51
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
52
52
|
with:
|
|
53
53
|
fetch-depth: 0
|
|
54
54
|
- name: Set up pixi
|
|
55
|
-
uses: prefix-dev/setup-pixi@
|
|
55
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
56
56
|
with:
|
|
57
57
|
environments: build
|
|
58
58
|
- name: Set version
|
|
59
59
|
run: pixi run -e build set-version
|
|
60
|
-
- uses: actions/setup-python@
|
|
60
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
61
61
|
with:
|
|
62
62
|
python-version: "3.10"
|
|
63
63
|
- name: Build wheel
|
|
@@ -58,7 +58,7 @@ jobs:
|
|
|
58
58
|
pull-requests: write
|
|
59
59
|
steps:
|
|
60
60
|
- name: ${{ github.event_name == 'pull_request_target' && 'Assign labels' || 'Update release draft' }}
|
|
61
|
-
uses: release-drafter/release-drafter@
|
|
61
|
+
uses: release-drafter/release-drafter@6db134d15f3909ccc9eefd369f02bd1e9cffdf97 # v6.2.0
|
|
62
62
|
with:
|
|
63
63
|
disable-releaser: ${{ github.event_name == 'pull_request_target' }}
|
|
64
64
|
disable-autolabeler: ${{ github.event_name == 'push' }}
|
|
@@ -19,14 +19,14 @@ jobs:
|
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
steps:
|
|
21
21
|
- name: Checkout branch
|
|
22
|
-
uses: actions/checkout@
|
|
22
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
23
23
|
with:
|
|
24
24
|
# needed for 'pre-commit-mirrors-insert-license'
|
|
25
25
|
fetch-depth: 0
|
|
26
26
|
- name: Set up pixi
|
|
27
|
-
uses: prefix-dev/setup-pixi@
|
|
27
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
28
28
|
with:
|
|
29
|
-
environments: default lint
|
|
29
|
+
environments: default lint polars-minimal
|
|
30
30
|
- name: Install Rust
|
|
31
31
|
run: rustup show
|
|
32
32
|
- name: Cache Rust dependencies
|
|
@@ -45,6 +45,7 @@ jobs:
|
|
|
45
45
|
environment: [py310, py311, py312, py313, py314]
|
|
46
46
|
with_optionals: [false]
|
|
47
47
|
include:
|
|
48
|
+
# Test with optional dependencies across OSes
|
|
48
49
|
- os: ubuntu-latest
|
|
49
50
|
environment: py314-optionals
|
|
50
51
|
with_optionals: true
|
|
@@ -54,11 +55,15 @@ jobs:
|
|
|
54
55
|
- os: macos-latest
|
|
55
56
|
environment: py314-optionals
|
|
56
57
|
with_optionals: true
|
|
58
|
+
# Test polars backward compatibility, only one OS
|
|
59
|
+
- os: ubuntu-latest
|
|
60
|
+
environment: polars-minimal
|
|
61
|
+
with_optionals: false
|
|
57
62
|
steps:
|
|
58
63
|
- name: Checkout branch
|
|
59
|
-
uses: actions/checkout@
|
|
64
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
60
65
|
- name: Set up pixi
|
|
61
|
-
uses: prefix-dev/setup-pixi@
|
|
66
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
62
67
|
with:
|
|
63
68
|
environments: ${{ matrix.environment }}
|
|
64
69
|
# FIXME: Remove when `s3_server` fixture does not start a process anymore
|
|
@@ -13,9 +13,9 @@ jobs:
|
|
|
13
13
|
id-token: write
|
|
14
14
|
steps:
|
|
15
15
|
- name: Checkout branch
|
|
16
|
-
uses: actions/checkout@
|
|
16
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
17
17
|
- name: Set up pixi
|
|
18
|
-
uses: prefix-dev/setup-pixi@
|
|
18
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
19
19
|
with:
|
|
20
20
|
environments: default
|
|
21
21
|
- name: Install Rust
|
|
@@ -23,9 +23,9 @@ jobs:
|
|
|
23
23
|
os: [ubuntu-latest, windows-latest]
|
|
24
24
|
steps:
|
|
25
25
|
- name: Checkout branch
|
|
26
|
-
uses: actions/checkout@
|
|
26
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
27
27
|
- name: Set up pixi
|
|
28
|
-
uses: prefix-dev/setup-pixi@
|
|
28
|
+
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
|
|
29
29
|
with:
|
|
30
30
|
environments: nightly
|
|
31
31
|
- name: Install polars nightly
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
|
|
36
36
|
steps:
|
|
37
37
|
- name: "Checkout code"
|
|
38
|
-
uses: actions/checkout@
|
|
38
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
39
39
|
with:
|
|
40
40
|
persist-credentials: false
|
|
41
41
|
|
|
@@ -74,6 +74,6 @@ jobs:
|
|
|
74
74
|
# Upload the results to GitHub's code scanning dashboard (optional).
|
|
75
75
|
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
|
76
76
|
- name: "Upload to code-scanning"
|
|
77
|
-
uses: github/codeql-action/upload-sarif@
|
|
77
|
+
uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3.29.5
|
|
78
78
|
with:
|
|
79
79
|
sarif_file: results.sarif
|
|
@@ -6,7 +6,7 @@ repos:
|
|
|
6
6
|
# workaround for https://github.com/prefix-dev/pixi/issues/1482
|
|
7
7
|
- id: pixi-install
|
|
8
8
|
name: pixi-install
|
|
9
|
-
entry: pixi install -e default -e lint
|
|
9
|
+
entry: pixi install -e default -e lint -e polars-minimal
|
|
10
10
|
language: system
|
|
11
11
|
always_run: true
|
|
12
12
|
require_serial: true
|
|
@@ -48,6 +48,13 @@ repos:
|
|
|
48
48
|
language: system
|
|
49
49
|
types: [python]
|
|
50
50
|
require_serial: true
|
|
51
|
+
# mypy with oldest supported polars version
|
|
52
|
+
- id: mypy
|
|
53
|
+
name: mypy-polars-minimal
|
|
54
|
+
entry: pixi run -e default-polars-minimal mypy --cache-dir .mypy_cache_polars_minimal
|
|
55
|
+
language: system
|
|
56
|
+
types: [python]
|
|
57
|
+
require_serial: true
|
|
51
58
|
# cargo-fmt
|
|
52
59
|
- id: cargo-fmt
|
|
53
60
|
name: cargo-fmt
|
|
@@ -152,9 +152,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
|
152
152
|
|
|
153
153
|
[[package]]
|
|
154
154
|
name = "bytes"
|
|
155
|
-
version = "1.
|
|
155
|
+
version = "1.11.1"
|
|
156
156
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
157
|
-
checksum = "
|
|
157
|
+
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
|
158
158
|
dependencies = [
|
|
159
159
|
"serde",
|
|
160
160
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataframely
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.10
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.14
|
|
10
10
|
Requires-Dist: fsspec>=2025.9
|
|
11
11
|
Requires-Dist: numpy
|
|
12
|
-
Requires-Dist: polars>=1.
|
|
12
|
+
Requires-Dist: polars>=1.35
|
|
13
13
|
Requires-Dist: typing-extensions ; python_full_version < '3.11'
|
|
14
14
|
Requires-Dist: deltalake ; extra == 'deltalake'
|
|
15
15
|
Requires-Dist: pyarrow ; extra == 'pyarrow'
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Copyright (c) QuantCo 2025-2026
|
|
2
2
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
from typing import Any
|
|
6
5
|
|
|
6
|
+
import polars as pl
|
|
7
|
+
|
|
7
8
|
|
|
8
9
|
class _DummyModule: # pragma: no cover
|
|
9
10
|
def __init__(self, module: str) -> None:
|
|
@@ -58,7 +59,6 @@ try:
|
|
|
58
59
|
except ImportError:
|
|
59
60
|
pa = _DummyModule("pyarrow")
|
|
60
61
|
|
|
61
|
-
|
|
62
62
|
# -------------------------------------- PYDANTIC ------------------------------------ #
|
|
63
63
|
|
|
64
64
|
try:
|
|
@@ -71,6 +71,24 @@ try:
|
|
|
71
71
|
except ImportError:
|
|
72
72
|
pydantic_core_schema = _DummyModule("pydantic_core_schema") # type: ignore
|
|
73
73
|
|
|
74
|
+
# --------------------------------------- POLARS ------------------------------------- #
|
|
75
|
+
|
|
76
|
+
_polars_version_tuple = tuple(
|
|
77
|
+
int(part) if part.isdigit() else part for part in pl.__version__.split(".")
|
|
78
|
+
)
|
|
79
|
+
if _polars_version_tuple < (1, 36):
|
|
80
|
+
from polars._typing import ( # type: ignore[attr-defined,unused-ignore]
|
|
81
|
+
PartitioningScheme as PartitionSchemeOrSinkDirectory,
|
|
82
|
+
)
|
|
83
|
+
elif _polars_version_tuple < (1, 38): # pragma: no cover
|
|
84
|
+
from polars.io.partition import ( # type: ignore[no-redef,attr-defined,unused-ignore]
|
|
85
|
+
_SinkDirectory as PartitionSchemeOrSinkDirectory,
|
|
86
|
+
)
|
|
87
|
+
else:
|
|
88
|
+
from polars.io.partition import ( # type: ignore[no-redef,attr-defined,unused-ignore]
|
|
89
|
+
PartitionBy as PartitionSchemeOrSinkDirectory,
|
|
90
|
+
)
|
|
91
|
+
|
|
74
92
|
# ------------------------------------------------------------------------------------ #
|
|
75
93
|
|
|
76
94
|
__all__ = [
|
|
@@ -78,6 +96,7 @@ __all__ = [
|
|
|
78
96
|
"DeltaTable",
|
|
79
97
|
"Dialect",
|
|
80
98
|
"MSDialect_pyodbc",
|
|
99
|
+
"PartitionSchemeOrSinkDirectory",
|
|
81
100
|
"pa",
|
|
82
101
|
"PGDialect_psycopg2",
|
|
83
102
|
"pydantic_core_schema",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) QuantCo 2025-2026
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
|
|
4
|
+
from fsspec import AbstractFileSystem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_file_prefix(fs: AbstractFileSystem) -> str:
|
|
8
|
+
match fs.protocol:
|
|
9
|
+
case "file":
|
|
10
|
+
return ""
|
|
11
|
+
case str():
|
|
12
|
+
return f"{fs.protocol}://"
|
|
13
|
+
case ["file", *_]:
|
|
14
|
+
return ""
|
|
15
|
+
case [str(proto), *_]:
|
|
16
|
+
return f"{proto}://"
|
|
17
|
+
case _:
|
|
18
|
+
raise ValueError(f"Unexpected fs.protocol: {fs.protocol}")
|
|
@@ -7,6 +7,8 @@ from typing import Any
|
|
|
7
7
|
import polars as pl
|
|
8
8
|
from fsspec import AbstractFileSystem, url_to_fs
|
|
9
9
|
|
|
10
|
+
from dataframely._storage import get_file_prefix
|
|
11
|
+
|
|
10
12
|
from ._base import (
|
|
11
13
|
SerializedCollection,
|
|
12
14
|
SerializedRules,
|
|
@@ -79,7 +81,9 @@ class ParquetStorageBackend(StorageBackend):
|
|
|
79
81
|
fs: AbstractFileSystem = url_to_fs(path)[0]
|
|
80
82
|
for key, lf in dfs.items():
|
|
81
83
|
destination = (
|
|
82
|
-
|
|
84
|
+
# Enforce that the path ends with a separator. Otherwise
|
|
85
|
+
# polars misbehaves on Windows.
|
|
86
|
+
fs.sep.join([path, key]) + fs.sep
|
|
83
87
|
if "partition_by" in kwargs
|
|
84
88
|
else fs.sep.join([path, f"{key}.parquet"])
|
|
85
89
|
)
|
|
@@ -107,7 +111,9 @@ class ParquetStorageBackend(StorageBackend):
|
|
|
107
111
|
fs: AbstractFileSystem = url_to_fs(path)[0]
|
|
108
112
|
for key, lf in dfs.items():
|
|
109
113
|
destination = (
|
|
110
|
-
|
|
114
|
+
# Enforce that the path ends with a separator. Otherwise
|
|
115
|
+
# polars misbehaves on Windows.
|
|
116
|
+
fs.sep.join([path, key]) + fs.sep
|
|
111
117
|
if "partition_by" in kwargs
|
|
112
118
|
else fs.sep.join([path, f"{key}.parquet"])
|
|
113
119
|
)
|
|
@@ -155,15 +161,7 @@ class ParquetStorageBackend(StorageBackend):
|
|
|
155
161
|
if is_file:
|
|
156
162
|
collection_types.append(_read_serialized_collection(source_path))
|
|
157
163
|
else:
|
|
158
|
-
prefix = (
|
|
159
|
-
""
|
|
160
|
-
if fs.protocol == "file"
|
|
161
|
-
else (
|
|
162
|
-
f"{fs.protocol}://"
|
|
163
|
-
if isinstance(fs.protocol, str)
|
|
164
|
-
else f"{fs.protocol[0]}://"
|
|
165
|
-
)
|
|
166
|
-
)
|
|
164
|
+
prefix = get_file_prefix(fs)
|
|
167
165
|
for file in fs.glob(fs.sep.join([source_path, "**", "*.parquet"])):
|
|
168
166
|
collection_types.append(
|
|
169
167
|
_read_serialized_collection(f"{prefix}{file}")
|
|
@@ -864,9 +864,8 @@ class Collection(BaseCollection, ABC):
|
|
|
864
864
|
members which are not provided in the current collection.
|
|
865
865
|
|
|
866
866
|
Args:
|
|
867
|
-
directory: The directory the Parquet files should be written to.
|
|
868
|
-
|
|
869
|
-
including all of its parents.
|
|
867
|
+
directory: The directory where the Parquet files should be written to.
|
|
868
|
+
The `mkdir` kwarg controls whether the directory is created if needed.
|
|
870
869
|
kwargs: Additional keyword arguments passed to :meth:`polars.DataFrame.write_parquet`.
|
|
871
870
|
`metadata` may only be provided if it is a dictionary.
|
|
872
871
|
|
|
@@ -29,10 +29,10 @@ class Decimal(OrdinalMixin[decimal.Decimal], Column):
|
|
|
29
29
|
*,
|
|
30
30
|
nullable: bool = False,
|
|
31
31
|
primary_key: bool = False,
|
|
32
|
-
min: decimal.Decimal | None = None,
|
|
33
|
-
min_exclusive: decimal.Decimal | None = None,
|
|
34
|
-
max: decimal.Decimal | None = None,
|
|
35
|
-
max_exclusive: decimal.Decimal | None = None,
|
|
32
|
+
min: decimal.Decimal | int | None = None,
|
|
33
|
+
min_exclusive: decimal.Decimal | int | None = None,
|
|
34
|
+
max: decimal.Decimal | int | None = None,
|
|
35
|
+
max_exclusive: decimal.Decimal | int | None = None,
|
|
36
36
|
check: Check | None = None,
|
|
37
37
|
alias: str | None = None,
|
|
38
38
|
metadata: dict[str, Any] | None = None,
|
|
@@ -70,6 +70,15 @@ class Decimal(OrdinalMixin[decimal.Decimal], Column):
|
|
|
70
70
|
names, the specified alias is the only valid name.
|
|
71
71
|
metadata: A dictionary of metadata to attach to the column.
|
|
72
72
|
"""
|
|
73
|
+
if isinstance(min, int):
|
|
74
|
+
min = decimal.Decimal(min)
|
|
75
|
+
if isinstance(min_exclusive, int):
|
|
76
|
+
min_exclusive = decimal.Decimal(min_exclusive)
|
|
77
|
+
if isinstance(max, int):
|
|
78
|
+
max = decimal.Decimal(max)
|
|
79
|
+
if isinstance(max_exclusive, int):
|
|
80
|
+
max_exclusive = decimal.Decimal(max_exclusive)
|
|
81
|
+
|
|
73
82
|
if min is not None:
|
|
74
83
|
_validate(min, precision, scale, "min")
|
|
75
84
|
if min_exclusive is not None:
|
|
@@ -10,11 +10,11 @@ from pathlib import Path
|
|
|
10
10
|
from typing import IO, TYPE_CHECKING, Any, Generic, TypeVar
|
|
11
11
|
|
|
12
12
|
import polars as pl
|
|
13
|
-
from polars.io.partition import _SinkDirectory as SinkDirectory
|
|
14
13
|
|
|
15
14
|
from dataframely._base_schema import BaseSchema
|
|
16
15
|
from dataframely._compat import deltalake
|
|
17
16
|
|
|
17
|
+
from ._compat import PartitionSchemeOrSinkDirectory
|
|
18
18
|
from ._storage import StorageBackend
|
|
19
19
|
from ._storage.delta import DeltaStorageBackend
|
|
20
20
|
from ._storage.parquet import ParquetStorageBackend
|
|
@@ -32,6 +32,7 @@ UNKNOWN_SCHEMA_NAME = "__DATAFRAMELY_UNKNOWN__"
|
|
|
32
32
|
|
|
33
33
|
S = TypeVar("S", bound=BaseSchema)
|
|
34
34
|
|
|
35
|
+
|
|
35
36
|
# ----------------------------------- FILTER RESULT ---------------------------------- #
|
|
36
37
|
|
|
37
38
|
|
|
@@ -73,7 +74,8 @@ class LazyFilterResult(NamedTuple, Generic[S]):
|
|
|
73
74
|
[self.result.lazy(), self.failure._lf], **kwargs
|
|
74
75
|
)
|
|
75
76
|
return FilterResult(
|
|
76
|
-
|
|
77
|
+
# Whether the type ignore is necessary depends on the polars version.
|
|
78
|
+
result=result_df, # type: ignore[arg-type,unused-ignore]
|
|
77
79
|
failure=FailureInfo(
|
|
78
80
|
failure_df.lazy(), self.failure._rule_columns, self.failure.schema
|
|
79
81
|
),
|
|
@@ -152,7 +154,8 @@ class FailureInfo(Generic[S]):
|
|
|
152
154
|
Args:
|
|
153
155
|
file: The file path or writable file-like object to which to write the
|
|
154
156
|
parquet file. This should be a path to a directory if writing a
|
|
155
|
-
partitioned dataset.
|
|
157
|
+
partitioned dataset. The `mkdir` kwarg controls whether the directory
|
|
158
|
+
is created if needed.
|
|
156
159
|
kwargs: Additional keyword arguments passed directly to
|
|
157
160
|
:meth:`polars.write_parquet`. ``metadata`` may only be provided if it
|
|
158
161
|
is a dictionary.
|
|
@@ -164,7 +167,9 @@ class FailureInfo(Generic[S]):
|
|
|
164
167
|
self._write(ParquetStorageBackend(), file=file, **kwargs)
|
|
165
168
|
|
|
166
169
|
def sink_parquet(
|
|
167
|
-
self,
|
|
170
|
+
self,
|
|
171
|
+
file: str | Path | IO[bytes] | PartitionSchemeOrSinkDirectory,
|
|
172
|
+
**kwargs: Any,
|
|
168
173
|
) -> None:
|
|
169
174
|
"""Stream the failure info to a single parquet file.
|
|
170
175
|
|
|
@@ -15,12 +15,11 @@ from typing import IO, Any, Literal, overload
|
|
|
15
15
|
import polars as pl
|
|
16
16
|
import polars.exceptions as plexc
|
|
17
17
|
from polars._typing import FileSource
|
|
18
|
-
from polars.io.partition import _SinkDirectory as SinkDirectory
|
|
19
18
|
|
|
20
19
|
from dataframely._compat import deltalake
|
|
21
20
|
|
|
22
21
|
from ._base_schema import ORIGINAL_COLUMN_PREFIX, BaseSchema
|
|
23
|
-
from ._compat import pa, sa
|
|
22
|
+
from ._compat import PartitionSchemeOrSinkDirectory, pa, sa
|
|
24
23
|
from ._match_to_schema import match_to_schema
|
|
25
24
|
from ._native import format_rule_failures
|
|
26
25
|
from ._plugin import all_rules, all_rules_horizontal, all_rules_required
|
|
@@ -55,9 +54,9 @@ if sys.version_info >= (3, 11):
|
|
|
55
54
|
else:
|
|
56
55
|
from typing_extensions import Self
|
|
57
56
|
|
|
58
|
-
|
|
59
57
|
_COLUMN_VALID = "__DATAFRAMELY_VALID__"
|
|
60
58
|
|
|
59
|
+
|
|
61
60
|
# ------------------------------------------------------------------------------------ #
|
|
62
61
|
# SCHEMA DEFINITION #
|
|
63
62
|
# ------------------------------------------------------------------------------------ #
|
|
@@ -554,8 +553,9 @@ class Schema(BaseSchema, ABC):
|
|
|
554
553
|
|
|
555
554
|
Returns:
|
|
556
555
|
The input eager or lazy frame, wrapped in a generic version of the
|
|
557
|
-
input's data frame type to reflect schema adherence.
|
|
558
|
-
|
|
556
|
+
input's data frame type to reflect schema adherence. Columns not defined
|
|
557
|
+
in the schema are removed from the output. This operation is guaranteed
|
|
558
|
+
to maintain input ordering of rows.
|
|
559
559
|
|
|
560
560
|
Raises:
|
|
561
561
|
SchemaError: If `eager=True` and the input data frame misses columns or
|
|
@@ -705,7 +705,8 @@ class Schema(BaseSchema, ABC):
|
|
|
705
705
|
Returns:
|
|
706
706
|
A tuple of the validated rows in the input data frame (potentially
|
|
707
707
|
empty) and a simple dataclass carrying information about the rows of the
|
|
708
|
-
data frame which could not be validated successfully.
|
|
708
|
+
data frame which could not be validated successfully. Columns not defined
|
|
709
|
+
in the schema are removed from the output. Just like in polars'
|
|
709
710
|
native :meth:`~polars.DataFrame.filter`, the order of rows in the returned
|
|
710
711
|
data frame is maintained.
|
|
711
712
|
|
|
@@ -885,7 +886,8 @@ class Schema(BaseSchema, ABC):
|
|
|
885
886
|
df: The data frame to write to the parquet file.
|
|
886
887
|
file: The file path or writable file-like object to which to write the
|
|
887
888
|
parquet file. This should be a path to a directory if writing a
|
|
888
|
-
partitioned dataset.
|
|
889
|
+
partitioned dataset. The `mkdir` kwarg controls whether the directory
|
|
890
|
+
is created if needed.
|
|
889
891
|
kwargs: Additional keyword arguments passed directly to
|
|
890
892
|
:meth:`polars.write_parquet`. `metadata` may only be provided if it
|
|
891
893
|
is a dictionary.
|
|
@@ -901,7 +903,7 @@ class Schema(BaseSchema, ABC):
|
|
|
901
903
|
cls,
|
|
902
904
|
lf: LazyFrame[Self],
|
|
903
905
|
/,
|
|
904
|
-
file: str | Path | IO[bytes] |
|
|
906
|
+
file: str | Path | IO[bytes] | PartitionSchemeOrSinkDirectory,
|
|
905
907
|
**kwargs: Any,
|
|
906
908
|
) -> None:
|
|
907
909
|
"""Stream a typed lazy frame with this schema to a parquet file.
|
|
@@ -10,6 +10,7 @@ from fsspec import AbstractFileSystem, url_to_fs
|
|
|
10
10
|
import dataframely as dy
|
|
11
11
|
from dataframely import FailureInfo, Validation
|
|
12
12
|
from dataframely._compat import deltalake
|
|
13
|
+
from dataframely._storage import get_file_prefix
|
|
13
14
|
from dataframely._storage.delta import _to_delta_table
|
|
14
15
|
|
|
15
16
|
# ----------------------------------- Schema -------------------------------------------
|
|
@@ -190,19 +191,7 @@ class CollectionStorageTester(ABC):
|
|
|
190
191
|
metadata."""
|
|
191
192
|
|
|
192
193
|
def _prefix_path(self, path: str, fs: AbstractFileSystem) -> str:
|
|
193
|
-
return f"{
|
|
194
|
-
|
|
195
|
-
@staticmethod
|
|
196
|
-
def _get_prefix(fs: AbstractFileSystem) -> str:
|
|
197
|
-
return (
|
|
198
|
-
""
|
|
199
|
-
if fs.protocol == "file"
|
|
200
|
-
else (
|
|
201
|
-
f"{fs.protocol}://"
|
|
202
|
-
if isinstance(fs.protocol, str)
|
|
203
|
-
else f"{fs.protocol[0]}://"
|
|
204
|
-
)
|
|
205
|
-
)
|
|
194
|
+
return f"{get_file_prefix(fs)}{path}"
|
|
206
195
|
|
|
207
196
|
|
|
208
197
|
class ParquetCollectionStorageTester(CollectionStorageTester):
|
|
@@ -33,3 +33,12 @@ class UserSchema(dy.Schema):
|
|
|
33
33
|
## How do I fix the ruff error `First argument of a method should be named self`?
|
|
34
34
|
|
|
35
35
|
See our documentation on [group rules](./quickstart.md#group-rules).
|
|
36
|
+
|
|
37
|
+
## What versions of `polars` does `dataframely` support?
|
|
38
|
+
|
|
39
|
+
Our CI automatically tests `dataframely` for a minimal supported version of `polars`, which is currently `1.35.*`,
|
|
40
|
+
and the latest stable version.
|
|
41
|
+
We aim to extend support for new `polars` versions as they are released.
|
|
42
|
+
|
|
43
|
+
If your `polars` version is not in the range of supported versions, `dataframely` may still work, but you may
|
|
44
|
+
encounter unexpected issues.
|