# Path: armet/exceptions.py
# class ImproperlyConfigured(BaseException):
#     """Something has been set up or configured incorrectly.
#     """
# 
# Path: armet/query/parser.py
# COMBINATORS = {
#     constants.LOGICAL_AND: operator.and_,
#     constants.LOGICAL_OR: operator.or_}
# OPERATOR_BEGIN_CHARS = set(x[0] for _, x in constants.OPERATORS if x)
# OPERATOR_SYMBOL_MAP = dict((v, k) for k, v in constants.OPERATORS if v)
# OPERATOR_KEYWORDS = set(k for k, _ in constants.OPERATORS)
# REVERSED_OPERATOR_SUFFIX_MAP = dict(
#     (v, k) for k, v in constants.OPERATOR_SUFFIX_MAP.items()
# )
# class Query(object):
# class QuerySegment(object):
# class NoopQuerySegment(object):
# class BinarySegmentCombinator(object):
# class UnarySegmentCombinator(object):
#     def __init__(self, original, parsed):
#     def __init__(self, **kwargs):
#     def __repr__(self):
#     def __str__(self):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, left, right, operation=operator.and_):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, operand, operation=operator.not_):
#     def __repr__(self):
#     def __str__(self):
# def parse(text, encoding='utf8'):
# def reset_stringio(buf):
# def split_segments(text, closing_paren=False):
# def combine(segments, combinators):
# def parse_directive(key):
# def parse_segment(text):
# 
# Path: armet/query/constants.py
# OPERATOR_EQUAL = 'exact', '=='
# OPERATOR_IEQUAL = 'iexact', '='
# OPERATOR_LT = 'lt', '<'
# OPERATOR_LTE = 'lte', '<='
# OPERATOR_GT = 'gt', '>'
# OPERATOR_GTE = 'gte', '>='
# OPERATOR_REGEX = 'regex', '*='
# OPERATOR_ISNULL = 'isnull', None
# OPERATOR_ICONTAINS = 'icontains', None
# OPERATOR_FALLBACK = OPERATOR_IEQUAL
# OPERATOR_SUFFIX_FALLBACK = OPERATOR_FALLBACK[0]
# OPERATOR_EQUALITY_FALLBACK = OPERATOR_FALLBACK[1]
# OPERATOR_MAP = {
#     OPERATOR_EQUAL: operator.eq,
#     OPERATOR_IEQUAL: lambda x, y: x.lower() == y.lower(),
#     OPERATOR_LT: operator.lt,
#     OPERATOR_LTE: operator.le,
#     OPERATOR_GT: operator.gt,
#     OPERATOR_GTE: operator.ge,
#     OPERATOR_REGEX: lambda x, y: re.search(y, x),
#     OPERATOR_ISNULL: lambda x: x is None,
#     OPERATOR_ICONTAINS: operator.contains,
# }
# OPERATORS = set(OPERATOR_MAP.keys())
# OPERATOR_SUFFIXES = set(filter(None, map(operator.itemgetter(0), OPERATORS)))
# OPERATOR_EQUALITIES = set(filter(None, map(operator.itemgetter(1), OPERATORS)))
# OPERATOR_SUFFIX_MAP = dict(
#     filter(operator.itemgetter(0),
#            map(lambda x: (x[0][0], x[1]),
#                OPERATOR_MAP.items())))
# OPERATOR_EQUALITY_MAP = dict(
#     filter(operator.itemgetter(0),
#            map(lambda x: (x[0][1], x[1]),
#                OPERATOR_MAP.items())))
# PATH_NEGATION = 'not'
# OPERATOR_NEGATION = '!'
# NEGATION = (PATH_NEGATION, OPERATOR_NEGATION)
# LOGICAL_AND = '&'
# LOGICAL_OR = ';'
# SEP_PATH = '.'
# SEP_VALUE = ','
# DIRECTIVE = ':'
# GROUP_BEGIN = '('
# GROUP_END = ')'
# 
# Path: armet/http/exceptions.py
# class BadRequest(BaseHTTPException):  # 400
#     status = client.BAD_REQUEST


import six
import operator
import sqlalchemy as sa
import functools
from functools import partial
from collections import Iterable
from copy import deepcopy
from six.moves import map, reduce
from armet.exceptions import ImproperlyConfigured
from armet.query import parser, Query, QuerySegment, constants
from armet.http.exceptions import BadRequest
from sqlalchemy.exc import InvalidRequestError

    def relate(self, target, other):
        # Resolve the relationship key.
        key = self._resolve_relation(other)
        if not key:
            raise BadRequest({
                '__all__': "Unable to link a '%s' to a '%s'." % (
                    type(target).__name__, type(other).__name__)})

        # Grab the set_ in question.
        set_ = getattr(target, key)

        # Append the relationship.
        set_.append(other)

        # Flush the target and expire attributes.
        self.session.flush()

        # Refresh the target object to avoid inconsistencies with storage.
        self.session.expire(target)

        # Ensure the user is authorized to perform this action.
        authz = self.meta.authorization
        if not authz.is_authorized(self.request.user, 'update', self, target):
            authz.unauthorized()

    def unrelate(self, target, other):
        # Resolve the relationship key.
        key = self._resolve_relation(other)
        if not key:

# Path: armet/exceptions.py
# class ImproperlyConfigured(BaseException):
#     """Something has been set up or configured incorrectly.
#     """
# 
# Path: armet/query/parser.py
# COMBINATORS = {
#     constants.LOGICAL_AND: operator.and_,
#     constants.LOGICAL_OR: operator.or_}
# OPERATOR_BEGIN_CHARS = set(x[0] for _, x in constants.OPERATORS if x)
# OPERATOR_SYMBOL_MAP = dict((v, k) for k, v in constants.OPERATORS if v)
# OPERATOR_KEYWORDS = set(k for k, _ in constants.OPERATORS)
# REVERSED_OPERATOR_SUFFIX_MAP = dict(
#     (v, k) for k, v in constants.OPERATOR_SUFFIX_MAP.items()
# )
# class Query(object):
# class QuerySegment(object):
# class NoopQuerySegment(object):
# class BinarySegmentCombinator(object):
# class UnarySegmentCombinator(object):
#     def __init__(self, original, parsed):
#     def __init__(self, **kwargs):
#     def __repr__(self):
#     def __str__(self):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, left, right, operation=operator.and_):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, operand, operation=operator.not_):
#     def __repr__(self):
#     def __str__(self):
# def parse(text, encoding='utf8'):
# def reset_stringio(buf):
# def split_segments(text, closing_paren=False):
# def combine(segments, combinators):
# def parse_directive(key):
# def parse_segment(text):
# 
# Path: armet/query/constants.py
# OPERATOR_EQUAL = 'exact', '=='
# OPERATOR_IEQUAL = 'iexact', '='
# OPERATOR_LT = 'lt', '<'
# OPERATOR_LTE = 'lte', '<='
# OPERATOR_GT = 'gt', '>'
# OPERATOR_GTE = 'gte', '>='
# OPERATOR_REGEX = 'regex', '*='
# OPERATOR_ISNULL = 'isnull', None
# OPERATOR_ICONTAINS = 'icontains', None
# OPERATOR_FALLBACK = OPERATOR_IEQUAL
# OPERATOR_SUFFIX_FALLBACK = OPERATOR_FALLBACK[0]
# OPERATOR_EQUALITY_FALLBACK = OPERATOR_FALLBACK[1]
# OPERATOR_MAP = {
#     OPERATOR_EQUAL: operator.eq,
#     OPERATOR_IEQUAL: lambda x, y: x.lower() == y.lower(),
#     OPERATOR_LT: operator.lt,
#     OPERATOR_LTE: operator.le,
#     OPERATOR_GT: operator.gt,
#     OPERATOR_GTE: operator.ge,
#     OPERATOR_REGEX: lambda x, y: re.search(y, x),
#     OPERATOR_ISNULL: lambda x: x is None,
#     OPERATOR_ICONTAINS: operator.contains,
# }
# OPERATORS = set(OPERATOR_MAP.keys())
# OPERATOR_SUFFIXES = set(filter(None, map(operator.itemgetter(0), OPERATORS)))
# OPERATOR_EQUALITIES = set(filter(None, map(operator.itemgetter(1), OPERATORS)))
# OPERATOR_SUFFIX_MAP = dict(
#     filter(operator.itemgetter(0),
#            map(lambda x: (x[0][0], x[1]),
#                OPERATOR_MAP.items())))
# OPERATOR_EQUALITY_MAP = dict(
#     filter(operator.itemgetter(0),
#            map(lambda x: (x[0][1], x[1]),
#                OPERATOR_MAP.items())))
# PATH_NEGATION = 'not'
# OPERATOR_NEGATION = '!'
# NEGATION = (PATH_NEGATION, OPERATOR_NEGATION)
# LOGICAL_AND = '&'
# LOGICAL_OR = ';'
# SEP_PATH = '.'
# SEP_VALUE = ','
# DIRECTIVE = ':'
# GROUP_BEGIN = '('
# GROUP_END = ')'
# 
# Path: armet/http/exceptions.py
# class BadRequest(BaseHTTPException):  # 400
#     status = client.BAD_REQUEST


# Path: armet/connectors/sqlalchemy/resources.py
import six
import operator
import sqlalchemy as sa
import functools
from functools import partial
from collections import Iterable
from copy import deepcopy
from six.moves import map, reduce
from armet.exceptions import ImproperlyConfigured
from armet.query import parser, Query, QuerySegment, constants
from armet.http.exceptions import BadRequest
from sqlalchemy.exc import InvalidRequestError


    def relate(self, target, other):
        # Resolve the relationship key.
        key = self._resolve_relation(other)
        if not key:
            raise BadRequest({
                '__all__': "Unable to link a '%s' to a '%s'." % (
                    type(target).__name__, type(other).__name__)})

        # Grab the set_ in question.
        set_ = getattr(target, key)

        # Append the relationship.
        set_.append(other)

        # Flush the target and expire attributes.
        self.session.flush()

        # Refresh the target object to avoid inconsistencies with storage.
        self.session.expire(target)

        # Ensure the user is authorized to perform this action.
        authz = self.meta.authorization
        if not authz.is_authorized(self.request.user, 'update', self, target):
            authz.unauthorized()

    def unrelate(self, target, other):
        # Resolve the relationship key.
        key = self._resolve_relation(other)
        if not key:

            raise BadRequest({