Skip to content

Commit 1bd8d8c

Browse files
authored
Merge pull request #71 from bystepii/json-fix
Add JSON serializer/deserializer
2 parents 790a003 + f295e2f commit 1bd8d8c

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

pydynamodb/sqlalchemy_dynamodb/pydynamodb.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
import re
33
from ..util import strtobool
4-
from typing import TYPE_CHECKING, cast, Optional, Sequence, List
4+
from typing import TYPE_CHECKING, Any, Callable, cast, Optional, Sequence, List
55

66
import pydynamodb
77
from pydynamodb.error import OperationalError, NotSupportedError
@@ -566,7 +566,6 @@ def visit_delete(self, delete_stmt, **kw):
566566

567567

568568
class DynamoDBTypeCompiler(GenericTypeCompiler):
569-
570569
def visit_FLOAT(self, type_, **kw):
571570
return self.visit_REAL(type_, **kw)
572571

@@ -623,6 +622,16 @@ class DynamoDBDialect(DefaultDialect):
623622

624623
_connect_options = dict() # type: ignore
625624

625+
def __init__(
626+
self,
627+
json_serializer: Optional[Callable[..., Any]] = None,
628+
json_deserializer: Optional[Callable[..., Any]] = None,
629+
**kwargs: Any,
630+
) -> None:
631+
DefaultDialect.__init__(self, **kwargs)
632+
self._json_serializer = json_serializer
633+
self._json_deserializer = json_deserializer
634+
626635
@classmethod
627636
def dbapi(cls):
628637
return pydynamodb

tests/test_sqlalchemy_dynamodb.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
from sqlalchemy.sql import text, select
33
from sqlalchemy.sql.schema import Column, MetaData, Table
4-
from sqlalchemy import Integer, String, Numeric
4+
from sqlalchemy import Integer, String, Numeric, JSON
55
from sqlalchemy.orm import declarative_base, Session
66

77
Base = declarative_base()
@@ -18,6 +18,7 @@ class _TestCase02(Base):
1818
key_sort = Column(Integer, primary_key=True)
1919
col_str = Column(String)
2020
col_num = Column(Numeric)
21+
col_json = Column(JSON)
2122
col_nested = Column()
2223

2324
class _User(Base):
@@ -109,7 +110,7 @@ def test_nested_data_insert(self, engine):
109110
"""
110111
INSERT INTO "%s" VALUE {
111112
'key_partition': :pk, 'key_sort': :sk,
112-
'col_str': :col1, 'col_nested': :col2
113+
'col_str': :col1, 'col_nested': :col2, 'col_json': :col3
113114
}
114115
"""
115116
% TESTCASE02_TABLE
@@ -124,13 +125,14 @@ def test_nested_data_insert(self, engine):
124125
"sk": 0,
125126
"col1": "test case nested 0",
126127
"col2": nested_data,
128+
"col3": nested_data,
127129
}
128130
conn.execute(text(sql_one_row_2_0_), params_2_0_)
129131

130132
rows = conn.execute(
131133
text(
132134
"""
133-
SELECT col_nested FROM %s WHERE key_partition = :pk
135+
SELECT col_nested, col_json FROM %s WHERE key_partition = :pk
134136
AND key_sort = :sk
135137
"""
136138
% TESTCASE02_TABLE
@@ -139,6 +141,7 @@ def test_nested_data_insert(self, engine):
139141
).fetchall()
140142
assert len(rows) == 1
141143
assert rows[0][0] == nested_data
144+
assert rows[0][1] == nested_data
142145

143146
def test_declarative_table_insert(self, engine):
144147
engine, conn = engine
@@ -286,6 +289,7 @@ def test_nested_data_in_reflect_table(self, engine):
286289
Column("key_sort", Integer),
287290
Column("col_str", String),
288291
Column("col_nested"),
292+
Column("col_json", JSON),
289293
)
290294
rows = conn.execute(
291295
table.select().where(
@@ -299,6 +303,11 @@ def test_nested_data_in_reflect_table(self, engine):
299303
"Key2": {"Val2-1", "Val2-2"},
300304
"Key3": "Val3",
301305
}
306+
assert rows[0].col_json == {
307+
"Key1": ["Val1-1", 1, {"Subkey1": "Val1-1"}],
308+
"Key2": {"Val2-1", "Val2-2"},
309+
"Key3": "Val3",
310+
}
302311

303312
def test_has_table_1(self, engine):
304313
engine, conn = engine

0 commit comments

Comments
 (0)