Skip to content

Commit 8947074

Browse files
committed
Fixes #402, fix custom JSON/JSONB type support.
1 parent be33ea8 commit 8947074

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

gino/dialects/asyncpg.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
from . import base
2323

24+
JSON_COLTYPE = 114
25+
JSONB_COLTYPE = 3802
26+
2427

2528
class AsyncpgDBAPI(base.BaseDBAPI):
2629
Error = asyncpg.PostgresError, asyncpg.InterfaceError
@@ -283,6 +286,15 @@ async def _on_metadata_drop_async(self, target, bind, checkfirst=False,
283286
await self.drop_async(bind=bind, checkfirst=checkfirst)
284287

285288

289+
class GinoNullType(sqltypes.NullType):
290+
def result_processor(self, dialect, coltype):
291+
if coltype == JSON_COLTYPE:
292+
return JSON().result_processor(dialect, coltype)
293+
if coltype == JSONB_COLTYPE:
294+
return JSONB().result_processor(dialect, coltype)
295+
return super().result_processor(dialect, coltype)
296+
297+
286298
# noinspection PyAbstractClass
287299
class AsyncpgDialect(PGDialect, base.AsyncDialectMixin):
288300
driver = 'asyncpg'
@@ -299,6 +311,7 @@ class AsyncpgDialect(PGDialect, base.AsyncDialectMixin):
299311
{
300312
ENUM: AsyncEnum,
301313
sqltypes.Enum: AsyncEnum,
314+
sqltypes.NullType: GinoNullType,
302315
}
303316
)
304317

gino/dialects/base.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
import weakref
33

44
from sqlalchemy import util
5-
from sqlalchemy.dialects.postgresql import JSON, JSONB
65

76
# noinspection PyProtectedMember
87
from ..engine import _SAConnection, _SAEngine, _DBAPIConnection
98
from ..loader import Loader
109

1110
DEFAULT = object()
12-
JSON_COLTYPE = 114
13-
JSONB_COLTYPE = 3802
1411

1512

1613
class BaseDBAPI:
@@ -375,13 +372,6 @@ def _init_statement_prepared(cls, dialect, connection, dbapi_connection,
375372
self.cursor = self.create_cursor()
376373
return self
377374

378-
def get_result_processor(self, type_, colname, coltype):
379-
if coltype == JSON_COLTYPE:
380-
return JSON().result_processor(self.dialect, coltype)
381-
if coltype == JSONB_COLTYPE:
382-
return JSONB().result_processor(self.dialect, coltype)
383-
return super().get_result_processor(type_, colname, coltype)
384-
385375

386376
class AsyncDialectMixin:
387377
cursor_cls = DBAPICursor

tests/test_json.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,21 @@ class Test(db.Model):
176176
age = db.IntegerProperty(default=18)
177177

178178

179-
async def test_t291(bind):
179+
async def test_t291_t402(bind):
180180
from gino.dialects.asyncpg import JSON, JSONB
181181

182+
class CustomJSONB(db.TypeDecorator):
183+
impl = JSONB
184+
185+
def process_result_value(self, *_):
186+
return 123
187+
182188
class PropsTest(db.Model):
183189
__tablename__ = 'props_test_291'
184190
profile = db.Column(JSONB(), nullable=False, server_default='{}')
185191
profile1 = db.Column(JSON(), nullable=False, server_default='{}')
192+
profile2 = db.Column(CustomJSONB(),
193+
nullable=False, server_default='{}')
186194

187195
bool = db.BooleanProperty()
188196
bool1 = db.BooleanProperty(prop_name='profile1')
@@ -197,5 +205,10 @@ class PropsTest(db.Model):
197205
assert isinstance(profile, dict)
198206
profile1 = await bind.scalar('SELECT profile1 FROM props_test_291')
199207
assert isinstance(profile1, dict)
208+
profile2 = await bind.scalar('SELECT profile2 FROM props_test_291')
209+
assert isinstance(profile2, dict)
210+
custom_profile2 = await bind.scalar(PropsTest.select('profile2'))
211+
assert isinstance(custom_profile2, int)
212+
assert custom_profile2 == 123
200213
finally:
201214
await PropsTest.gino.drop()

0 commit comments

Comments
 (0)