Skip to content

Commit a900207

Browse files
authored
Merge pull request #408 from wwwjfy/json-prop-check
refs #406, define exception on unknown json prop
2 parents add3ce1 + 2bbf930 commit a900207

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

gino/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ class NoSuchRowError(GinoException):
88

99
class UninitializedError(GinoException):
1010
pass
11+
12+
13+
class UnknownJSONPropertyError(GinoException):
14+
pass

gino/json_support.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import sqlalchemy as sa
44

5+
from .exceptions import UnknownJSONPropertyError
6+
57
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%f'
68
NONE = object()
79

@@ -54,8 +56,15 @@ def get_profile(self, instance):
5456
if instance.__profile__ is None:
5557
props = type(instance).__dict__
5658
instance.__profile__ = {}
57-
for key, value in (getattr(instance, self.prop_name, None)
58-
or {}).items():
59+
for key, value in (
60+
getattr(instance, self.prop_name, None) or {}
61+
).items():
62+
if key not in props:
63+
raise UnknownJSONPropertyError(
64+
'`{}` is found in `{}` of instance {}, '
65+
'but it is not defined'.format(
66+
key, self.prop_name, instance
67+
))
5968
instance.__profile__[key] = props[key].decode(value)
6069
return instance.__profile__
6170

tests/test_json.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import pytest
22
from datetime import datetime, timedelta
33

4+
from gino.exceptions import UnknownJSONPropertyError
5+
46
from .models import db, User, UserType
57

68
pytestmark = pytest.mark.asyncio
@@ -167,6 +169,25 @@ class PropsTest(db.Model):
167169
await PropsTest.gino.drop()
168170

169171

172+
# noinspection PyUnusedLocal
173+
async def test_unknown_properties(bind):
174+
from gino.dialects.asyncpg import JSONB
175+
176+
class PropsTest1(db.Model):
177+
__tablename__ = 'props_test1'
178+
profile = db.Column(JSONB(), nullable=False, server_default='{}')
179+
bool = db.BooleanProperty()
180+
181+
await PropsTest1.gino.create()
182+
try:
183+
# bool1 is not defined in the model
184+
t = await PropsTest1.create(profile=dict(bool1=True))
185+
with pytest.raises(UnknownJSONPropertyError, match=r'bool1.*profile'):
186+
t.to_dict()
187+
finally:
188+
await PropsTest1.gino.drop()
189+
190+
170191
async def test_no_profile():
171192
with pytest.raises(AttributeError, match=r'JSON\[B\] column'):
172193
# noinspection PyUnusedLocal

0 commit comments

Comments
 (0)