Skip to content

Commit 053cea5

Browse files
committed
Update to crate-2.0.0, which uses orjson for JSON marshalling
1 parent a69a9ca commit 053cea5

File tree

5 files changed

+14
-61
lines changed

5 files changed

+14
-61
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44
- Fixed connectivity for `jobstats collect`
55
- Refactored code and improved CLI interface of `ctk info` vs. `ctk cfr`
6+
- Dependencies: Updated to `crate-2.0.0`, which uses `orjson` for JSON marshalling
67

78
## 2025/01/13 v0.0.30
89
- Dependencies: Minimize dependencies of core installation,

cratedb_toolkit/cfr/systable.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from cratedb_toolkit.info.core import InfoContainer
3333
from cratedb_toolkit.util import DatabaseAdapter
3434
from cratedb_toolkit.util.cli import error_logger
35-
from cratedb_toolkit.util.sqlalchemy import patch_encoder
3635

3736
logger = logging.getLogger(__name__)
3837

@@ -256,6 +255,3 @@ def load_table(self, path: Path) -> "pl.DataFrame":
256255
return pl.read_parquet(path)
257256
else:
258257
raise NotImplementedError(f"Input format not implemented: {path.suffix}")
259-
260-
261-
patch_encoder()

cratedb_toolkit/util/sqlalchemy.py

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,8 @@
44
TODO: Refactor to `crate` or `sqlalchemy-cratedb` packages.
55
"""
66

7-
import calendar
8-
import datetime as dt
9-
import json
10-
from decimal import Decimal
11-
from uuid import UUID
12-
13-
from sqlalchemy_cratedb.dialect import TYPES_MAP
14-
15-
try:
16-
import numpy as np
17-
18-
has_numpy = True
19-
except ImportError:
20-
has_numpy = False
21-
227
from sqlalchemy import types as sqltypes
23-
24-
25-
def patch_encoder():
26-
import crate.client.http
27-
28-
crate.client.http.CrateJsonEncoder = CrateJsonEncoderWithNumPy
29-
30-
31-
class CrateJsonEncoderWithNumPy(json.JSONEncoder):
32-
epoch_aware = dt.datetime(1970, 1, 1, tzinfo=dt.timezone.utc)
33-
epoch_naive = dt.datetime(1970, 1, 1)
34-
35-
def default(self, o):
36-
# Vanilla CrateDB Python.
37-
if isinstance(o, (Decimal, UUID)):
38-
return str(o)
39-
if isinstance(o, dt.datetime):
40-
if o.tzinfo is not None:
41-
delta = o - self.epoch_aware
42-
else:
43-
delta = o - self.epoch_naive
44-
return int(delta.microseconds / 1000.0 + (delta.seconds + delta.days * 24 * 3600) * 1000.0)
45-
if isinstance(o, dt.date):
46-
return calendar.timegm(o.timetuple()) * 1000
47-
48-
# NumPy ndarray and friends.
49-
# https://stackoverflow.com/a/49677241
50-
if has_numpy:
51-
if isinstance(o, np.integer):
52-
return int(o)
53-
elif isinstance(o, np.floating):
54-
return float(o)
55-
elif isinstance(o, np.ndarray):
56-
return o.tolist()
57-
return json.JSONEncoder.default(self, o)
8+
from sqlalchemy_cratedb.dialect import TYPES_MAP
589

5910

6011
def patch_types_map():

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ dependencies = [
100100
"python-dotenv<2",
101101
"python-slugify<9",
102102
"pyyaml<7",
103-
"sqlalchemy-cratedb>=0.40,<1",
103+
"sqlalchemy-cratedb>=0.41.0.dev1",
104104
"sqlparse<0.6",
105105
"tqdm<5",
106106
'typing-extensions<5; python_version <= "3.7"',

tests/sqlalchemy/test_patch.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import datetime
2-
import json
32

43
import pytest
54
import sqlalchemy as sa
5+
from crate.client.http import json_dumps
66

7-
from cratedb_toolkit.util.sqlalchemy import CrateJsonEncoderWithNumPy
87
from tests.conftest import TESTDRIVE_DATA_SCHEMA
98

109

@@ -48,18 +47,24 @@ def test_inspector_patched(database, needs_sqlalchemy2):
4847
def test_json_encoder_date():
4948
"""
5049
Verify the extended JSON encoder also accepts Python's `date` types.
50+
51+
TODO: Move to different test file, as this no longer requires
52+
monkeypatching after using orjson for marshalling.
5153
"""
5254
data = {"date": datetime.date(2024, 6, 4)}
53-
encoded = json.dumps(data, cls=CrateJsonEncoderWithNumPy)
54-
assert encoded == '{"date": 1717459200000}'
55+
encoded = json_dumps(data)
56+
assert encoded == b'{"date":"2024-06-04"}'
5557

5658

5759
def test_json_encoder_numpy():
5860
"""
5961
Verify the extended JSON encoder also accepts NumPy types.
62+
63+
TODO: Move to different test file, as this no longer requires
64+
monkeypatching after using orjson for marshalling.
6065
"""
6166
np = pytest.importorskip("numpy")
6267

6368
data = {"scalar-int": np.float32(42.42).astype(int), "scalar-float": np.float32(42.42), "ndarray": np.ndarray([1])}
64-
encoded = json.dumps(data, cls=CrateJsonEncoderWithNumPy)
65-
assert encoded == """{"scalar-int": 42, "scalar-float": 42.41999816894531, "ndarray": [2.08e-322]}"""
69+
encoded = json_dumps(data)
70+
assert encoded == b"""{"scalar-int":42,"scalar-float":42.42,"ndarray":[2.08e-322]}"""

0 commit comments

Comments
 (0)