|
|
|
''' SQL conventions and custom Encoders '''
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
|
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
|
|
from sqlalchemy.schema import MetaData
|
|
|
|
from sqlalchemy.types import TypeDecorator, Unicode
|
|
|
|
|
|
|
|
# Recommended naming convention used by Alembic, as various different database
|
|
|
|
# providers will autogenerate vastly different names making migrations more
|
|
|
|
# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
|
|
|
|
NAMING_CONVENTION = {
|
|
|
|
"ix": "ix_%(column_0_label)s",
|
|
|
|
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
|
|
|
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
|
|
|
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
|
|
|
"pk": "pk_%(table_name)s"
|
|
|
|
}
|
|
|
|
|
|
|
|
metadata = MetaData(naming_convention=NAMING_CONVENTION)
|
|
|
|
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
|