diff --git a/CHANGELOG.md b/CHANGELOG.md index 77abe26..0dcd7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Please see [MIGRATING.md](./MIGRATING.md) for information on breaking changes. - Endpoints which return system fields before the record list - Example python script +- Columns with mixed and incompatible datatypes ### Changed diff --git a/src/ldlite/_jsonx.py b/src/ldlite/_jsonx.py index 4983e94..86ae0c0 100644 --- a/src/ldlite/_jsonx.py +++ b/src/ldlite/_jsonx.py @@ -161,7 +161,7 @@ def _compile_attrs( # noqa: C901, PLR0912, PLR0913 if depth > max_depth: return table = _table_name(parents) - qkey = {} + qkey: dict[str, Attr] = {} for k, a in quasikey.items(): qkey[k] = Attr(a.name, a.datatype, order=1) arrays: list[tuple[str, list[JsonValue], str]] = [] @@ -170,6 +170,11 @@ def _compile_attrs( # noqa: C901, PLR0912, PLR0913 if k is None or v is None: continue attr = prefix + k + prev_attr = ( + newattrs[table][attr] + if table in newattrs and attr in newattrs[table] + else None + ) if isinstance(v, dict): if depth == max_depth: newattrs[table][attr] = Attr( @@ -181,6 +186,11 @@ def _compile_attrs( # noqa: C901, PLR0912, PLR0913 objects.append((attr, v, k)) elif isinstance(v, list): arrays.append((attr, v, k)) + elif prev_attr and prev_attr.datatype == "varchar": + # If a column has already been through this check + # and determined to be a varchar it means that + # we can't type it as anything more specific later + qkey[attr] = prev_attr elif isinstance(v, bool): a = Attr(decode_camel_case(attr), "boolean", order=3) qkey[attr] = a diff --git a/tests/test_cases/query_cases.py b/tests/test_cases/query_cases.py index b414371..a11bfc2 100644 --- a/tests/test_cases/query_cases.py +++ b/tests/test_cases/query_cases.py @@ -604,6 +604,7 @@ def case_null_records(self) -> QueryCase: ], ) + # https://github.com/library-data-platform/ldlite/issues/52 def case_erm_keys(self) -> QueryCase: return QueryCase( json_depth=3, @@ -638,3 +639,41 @@ def case_erm_keys(self) -> QueryCase: ("prefix__t", "id"), ], ) + + # https://github.com/library-data-platform/ldlite/issues/54 + def case_mixed_uuid(self) -> QueryCase: + return QueryCase( + json_depth=3, + values={ + "prefix": [ + { + "purchaseOrders": [ + { + "id": "aaaa", + "value": "value", + }, + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": 15, + }, + ], + }, + ], + }, + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value"], + [ + ("aaaa", "value"), + ("b096504a-3d54-4664-9bf5-1b872466fd66", "15"), + ], + ), + "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + )