Browse Source

added custom column type JsonEncoder

rework
Holger Frey 7 years ago
parent
commit
a0b50a81d6
  1. 23
      ordr/models/meta.py
  2. 0
      ordr/tests/models/__init__.py
  3. 35
      ordr/tests/models/meta.py

23
ordr/models/meta.py

@ -1,5 +1,10 @@
''' SQL conventions and custom Encoders '''
import json
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import MetaData from sqlalchemy.schema import MetaData
from sqlalchemy.types import TypeDecorator, Unicode
# Recommended naming convention used by Alembic, as various different database # Recommended naming convention used by Alembic, as various different database
# providers will autogenerate vastly different names making migrations more # providers will autogenerate vastly different names making migrations more
@ -14,3 +19,21 @@ NAMING_CONVENTION = {
metadata = MetaData(naming_convention=NAMING_CONVENTION) metadata = MetaData(naming_convention=NAMING_CONVENTION)
Base = declarative_base(metadata=metadata) Base = declarative_base(metadata=metadata)
class JsonEncoder(TypeDecorator):
''' Custom type for storing data structures as json-encoded string. '''
impl = Unicode
def process_bind_param(self, value, dialect):
''' inbound (to database) '''
if value is not None:
value = json.dumps(value)
return value
def process_result_value(self, value, dialect):
''' outbound (from database) '''
if value is not None:
value = json.loads(value)
return value

0
ordr/tests/models/__init__.py

35
ordr/tests/models/meta.py

@ -0,0 +1,35 @@
import pytest
@pytest.mark.parametrize(
'value,expected', [
(None, None),
([1, 2, 3], '[1, 2, 3]'),
({'a':1, 'b':2}, '{"a": 1, "b": 2}'),
]
)
def test_json_encoder_bind(value, expected):
from ordr.models.meta import JsonEncoder
encoder = JsonEncoder()
assert encoder.process_bind_param(value, None) == expected
@pytest.mark.parametrize(
'value,expected', [
(None, None),
('[1, 2, 3]', [1, 2, 3]),
('{"a": 1, "b":2}', {'a':1, 'b':2}),
]
)
def test_json_encoder_result(value, expected):
from ordr.models.meta import JsonEncoder
encoder = JsonEncoder()
assert encoder.process_result_value(value, None) == expected
@pytest.mark.parametrize('value', [None, [1, 2, 3], {'a':1, 'b':2}])
def test_json_encoder_bind_and_result(value):
from ordr.models.meta import JsonEncoder
encoder = JsonEncoder()
result = encoder.process_bind_param(value, None)
assert encoder.process_result_value(result, None) == value