|
17 | 17 |
|
18 | 18 | import base64
|
19 | 19 | import datetime as py_datetime
|
| 20 | +import importlib |
20 | 21 | import struct
|
| 22 | +import types |
21 | 23 | from abc import ABC, abstractmethod
|
22 | 24 | from enum import IntEnum
|
23 | 25 | from functools import singledispatch
|
|
28 | 30 | import mmh3
|
29 | 31 | from pydantic import Field, PositiveInt, PrivateAttr
|
30 | 32 |
|
| 33 | +from pyiceberg.exceptions import NotInstalledError |
31 | 34 | from pyiceberg.expressions import (
|
32 | 35 | BoundEqualTo,
|
33 | 36 | BoundGreaterThan,
|
|
106 | 109 | TRUNCATE_PARSER = ParseNumberFromBrackets(TRUNCATE)
|
107 | 110 |
|
108 | 111 |
|
| 112 | +def _try_import(module_name: str, extras_name: Optional[str] = None) -> types.ModuleType: |
| 113 | + try: |
| 114 | + return importlib.import_module(module_name) |
| 115 | + except ImportError: |
| 116 | + if extras_name: |
| 117 | + msg = f'{module_name} needs to be installed. pip install "pyiceberg[{extras_name}]"' |
| 118 | + else: |
| 119 | + msg = f"{module_name} needs to be installed." |
| 120 | + raise NotInstalledError(msg) from None |
| 121 | + |
| 122 | + |
109 | 123 | def _transform_literal(func: Callable[[L], L], lit: Literal[L]) -> Literal[L]:
|
110 | 124 | """Small helper to upwrap the value from the literal, and wrap it again."""
|
111 | 125 | return literal(func(lit.value))
|
@@ -382,8 +396,7 @@ def __repr__(self) -> str:
|
382 | 396 | return f"BucketTransform(num_buckets={self._num_buckets})"
|
383 | 397 |
|
384 | 398 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
385 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
386 |
| - |
| 399 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
387 | 400 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.bucket, self._num_buckets)
|
388 | 401 |
|
389 | 402 | @property
|
@@ -509,9 +522,8 @@ def __repr__(self) -> str:
|
509 | 522 | return "YearTransform()"
|
510 | 523 |
|
511 | 524 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
512 |
| - import pyarrow as pa |
513 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
514 |
| - |
| 525 | + pa = _try_import("pyarrow") |
| 526 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
515 | 527 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.year, expected_type=pa.int32())
|
516 | 528 |
|
517 | 529 |
|
@@ -570,8 +582,8 @@ def __repr__(self) -> str:
|
570 | 582 | return "MonthTransform()"
|
571 | 583 |
|
572 | 584 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
573 |
| - import pyarrow as pa |
574 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
| 585 | + pa = _try_import("pyarrow") |
| 586 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
575 | 587 |
|
576 | 588 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.month, expected_type=pa.int32())
|
577 | 589 |
|
@@ -639,8 +651,8 @@ def __repr__(self) -> str:
|
639 | 651 | return "DayTransform()"
|
640 | 652 |
|
641 | 653 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
642 |
| - import pyarrow as pa |
643 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
| 654 | + pa = _try_import("pyarrow", extras_name="pyarrow") |
| 655 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
644 | 656 |
|
645 | 657 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.day, expected_type=pa.int32())
|
646 | 658 |
|
@@ -692,7 +704,7 @@ def __repr__(self) -> str:
|
692 | 704 | return "HourTransform()"
|
693 | 705 |
|
694 | 706 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
695 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
| 707 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
696 | 708 |
|
697 | 709 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.hour)
|
698 | 710 |
|
@@ -915,7 +927,7 @@ def __repr__(self) -> str:
|
915 | 927 | return f"TruncateTransform(width={self._width})"
|
916 | 928 |
|
917 | 929 | def pyarrow_transform(self, source: IcebergType) -> "Callable[[pa.Array], pa.Array]":
|
918 |
| - from pyiceberg_core import transform as pyiceberg_core_transform |
| 930 | + pyiceberg_core_transform = _try_import("pyiceberg_core", extras_name="pyiceberg-core").transform |
919 | 931 |
|
920 | 932 | return _pyiceberg_transform_wrapper(pyiceberg_core_transform.truncate, self._width)
|
921 | 933 |
|
|
0 commit comments