1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
from __future__ import absolute_import
import six
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql.base import ischema_names
from ..exceptions import ImproperlyConfigured
json = None
try:
import anyjson as json
except ImportError:
import json as json
try:
from sqlalchemy.dialects.postgresql import JSON
has_postgres_json = True
except ImportError:
class PostgresJSONType(sa.types.UserDefinedType):
"""
Text search vector type for postgresql.
"""
def get_col_spec(self):
return 'json'
ischema_names['json'] = PostgresJSONType
has_postgres_json = False
class JSONType(sa.types.TypeDecorator):
"""
JSONType offers way of saving JSON data structures to database. On
PostgreSQL the underlying implementation of this data type is 'json' while
on other databases its simply 'text'.
::
from sqlalchemy_utils import JSONType
class Product(Base):
__tablename__ = 'product'
id = sa.Column(sa.Integer, autoincrement=True)
name = sa.Column(sa.Unicode(50))
details = sa.Column(JSONType)
product = Product()
product.details = {
'color': 'red',
'type': 'car',
'max-speed': '400 mph'
}
session.commit()
"""
impl = sa.UnicodeText
def __init__(self, *args, **kwargs):
if json is None:
raise ImproperlyConfigured(
'JSONType needs anyjson package installed.'
)
super(JSONType, self).__init__(*args, **kwargs)
def load_dialect_impl(self, dialect):
if dialect.name == 'postgresql':
# Use the native JSON type.
if has_postgres_json:
return dialect.type_descriptor(JSON())
else:
return dialect.type_descriptor(PostgresJSONType())
else:
return dialect.type_descriptor(self.impl)
def process_bind_param(self, value, dialect):
if dialect.name == 'postgresql' and has_postgres_json:
return value
if value is not None:
value = six.text_type(json.dumps(value))
return value
def process_result_value(self, value, dialect):
if dialect.name == 'postgresql':
return value
if value is not None:
value = json.loads(value)
return value
|