Skip to content

Commit 7024d54

Browse files
committed
Rework some tests
1 parent 3a7ed01 commit 7024d54

File tree

5 files changed

+94
-14
lines changed

5 files changed

+94
-14
lines changed

pyiceberg/utils/schema_conversion.py

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ def _convert_logical_type(self, avro_logical_type: Dict[str, Any]) -> IcebergTyp
379379
physical_type = avro_logical_type["type"]
380380
if logical_type == "decimal":
381381
return self._convert_logical_decimal_type(avro_logical_type)
382+
elif logical_type == "geography":
383+
return self._convert_logical_geography_type(avro_logical_type)
384+
elif logical_type == "geometry":
385+
return self._convert_logical_geometry_type(avro_logical_type)
382386
elif logical_type == "map":
383387
return self._convert_logical_map_type(avro_logical_type)
384388
elif logical_type == "timestamp-micros":
@@ -418,6 +422,58 @@ def _convert_logical_decimal_type(self, avro_type: Dict[str, Any]) -> DecimalTyp
418422
"""
419423
return DecimalType(precision=avro_type["precision"], scale=avro_type["scale"])
420424

425+
def _convert_logical_geography_type(self, avro_type: Dict[str, Any]) -> GeographyType:
426+
"""Convert an avro type to an Iceberg GeographyType.
427+
428+
Args:
429+
avro_type: The Avro type.
430+
431+
Examples:
432+
>>> from pyiceberg.utils.schema_conversion import AvroSchemaConversion
433+
>>> avro_geography_type = {
434+
... "type": "bytes",
435+
... "logicalType": "geography",
436+
... "crs": 'OGC:CRS84',
437+
... "edge_algorithm": 'spherical'
438+
... }
439+
>>> actual = AvroSchemaConversion()._convert_logical_decimal_type(geography)
440+
>>> expected = GeographyType(
441+
... crs='OGC:CRS84',
442+
... edge_algorithm=EdgeAlgorithm.SPHERICAL
443+
... )
444+
>>> actual == expected
445+
True
446+
447+
Returns:
448+
A Iceberg GeographyType.
449+
"""
450+
return GeographyType(crs=avro_type["crs"], edge_algorithm=avro_type["edge_algorithm"])
451+
452+
def _convert_logical_geometry_type(self, avro_type: Dict[str, Any]) -> GeometryType:
453+
"""Convert an avro type to an Iceberg GeometryType.
454+
455+
Args:
456+
avro_type: The Avro type.
457+
458+
Examples:
459+
>>> from pyiceberg.utils.schema_conversion import AvroSchemaConversion
460+
>>> avro_geometry_type = {
461+
... "type": "bytes",
462+
... "logicalType": "geometry",
463+
... "crs": "OGC:CRS84
464+
... }
465+
>>> actual = AvroSchemaConversion()._convert_logical_decimal_type(avro_geometry_type)
466+
>>> expected = GeometryType(
467+
... crs="OGC:CRS84"
468+
... )
469+
>>> actual == expected
470+
True
471+
472+
Returns:
473+
A Iceberg GeometryType.
474+
"""
475+
return GeometryType(crs=avro_type["crs"])
476+
421477
def _convert_logical_map_type(self, avro_type: Dict[str, Any]) -> MapType:
422478
"""Convert an avro map type to an Iceberg MapType.
423479
@@ -643,17 +699,17 @@ def visit_binary(self, binary_type: BinaryType) -> AvroType:
643699

644700
def visit_geography(self, geography_type: GeographyType) -> AvroType:
645701
return {
646-
"type": "bytes",
647-
"logicalType": "geography",
648-
"crs": geography_type.crs,
702+
"type": "bytes",
703+
"logicalType": "geography",
704+
"crs": geography_type.crs,
649705
"edge_algorithm": geography_type.edge_algorithm,
650706
}
651707

652708
def visit_geometry(self, geometry_type: GeometryType) -> AvroType:
653709
return {
654-
"type": "bytes",
655-
"logicalType": "geometry",
656-
"crs": geometry_type.crs,
710+
"type": "bytes",
711+
"logicalType": "geometry",
712+
"crs": geometry_type.crs,
657713
}
658714

659715
def visit_unknown(self, unknown_type: UnknownType) -> AvroType:

tests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
DoubleType,
8383
FixedType,
8484
FloatType,
85+
GeographyType,
86+
GeometryType,
8587
IntegerType,
8688
ListType,
8789
LongType,
@@ -352,6 +354,8 @@ def table_schema_with_all_types() -> Schema:
352354
NestedField(field_id=22, name="inner_int", field_type=IntegerType(), required=True),
353355
),
354356
),
357+
NestedField(field_id=23, name="geography", field_type=GeographyType(), required=True),
358+
NestedField(field_id=24, name="geometry", field_type=GeometryType(), required=True),
355359
schema_id=1,
356360
identifier_field_ids=[2],
357361
)

tests/test_transforms.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
DoubleType,
101101
FixedType,
102102
FloatType,
103+
GeographyType,
104+
GeometryType,
103105
IntegerType,
104106
LongType,
105107
NestedField,
@@ -168,6 +170,16 @@
168170
TimestamptzNanoType(),
169171
-1207196810,
170172
),
173+
(
174+
b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xf0?", # POINT (1 1) in WKB
175+
GeographyType(),
176+
-1769831280
177+
),
178+
(
179+
b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xf0?", # POINT (1 1) in WKB
180+
GeometryType(),
181+
-1769831280
182+
)
171183
],
172184
)
173185
def test_bucket_hash_values(test_input: Any, test_type: PrimitiveType, expected: Any) -> None:

tests/test_types.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@
6262
(10, StringType),
6363
(11, UUIDType),
6464
(12, BinaryType),
65-
(13, GeographyType),
66-
(14, GeometryType),
6765
]
6866

6967
primitive_types = {
@@ -79,8 +77,6 @@
7977
"string": StringType,
8078
"uuid": UUIDType,
8179
"binary": BinaryType,
82-
"geography": GeographyType,
83-
"geometry": GeometryType,
8480
}
8581

8682

@@ -105,8 +101,6 @@ def test_repr_primitive_types(input_index: int, input_type: Type[PrimitiveType])
105101
(StringType(), True),
106102
(UUIDType(), True),
107103
(BinaryType(), True),
108-
(GeographyType(), True),
109-
(GeometryType(), True),
110104
(DecimalType(32, 3), True),
111105
(FixedType(8), True),
112106
(ListType(1, StringType(), True), False),
@@ -520,7 +514,7 @@ def test_str_geography() -> None:
520514

521515

522516
def test_repr_geography() -> None:
523-
assert repr(GeographyType()) == "GeographyType()"
517+
assert repr(GeographyType()) == "GeographyType(crs=None, edge_algorithm=None)"
524518

525519

526520
def test_serialization_geometry() -> None:
@@ -536,7 +530,7 @@ def test_str_geometry() -> None:
536530

537531

538532
def test_repr_geometry() -> None:
539-
assert repr(GeometryType()) == "GeometryType()"
533+
assert repr(GeometryType()) == "GeometryType(crs=None)"
540534

541535

542536
def test_serialization_decimal() -> None:

tests/utils/test_schema_conversion.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
DateType,
2727
DecimalType,
2828
FixedType,
29+
GeographyType,
30+
GeometryType,
2931
IntegerType,
3032
ListType,
3133
LongType,
@@ -347,6 +349,18 @@ def test_convert_timestamp_micros_type() -> None:
347349
assert actual == TimestampType()
348350

349351

352+
def test_convert_geography_type() -> None:
353+
avro_logical_type = {"type": "bytes", "logicalType": "geography", "crs": "OGC:CRS84", "edge_algorithm": None}
354+
actual = AvroSchemaConversion()._convert_logical_type(avro_logical_type)
355+
assert actual == GeographyType()
356+
357+
358+
def test_convert_geometry_type() -> None:
359+
avro_logical_type = {"type": "string", "logicalType": "geometry", "crs": "OGC:CRS84"}
360+
actual = AvroSchemaConversion()._convert_logical_type(avro_logical_type)
361+
assert actual == GeometryType()
362+
363+
350364
def test_unknown_logical_type() -> None:
351365
"""Test raising a ValueError when converting an unknown logical type as part of an Avro schema conversion"""
352366
avro_logical_type = {"type": "bytes", "logicalType": "date"}

0 commit comments

Comments
 (0)