Пример #1
0
    def test_bitflags(self):
        sym1 = util.symbol('sym1', canonical=1)
        sym2 = util.symbol('sym2', canonical=2)

        assert sym1 & sym1
        assert not sym1 & sym2
        assert not sym1 & sym1 & sym2
Пример #2
0
 def _on_field_change(offer, value, old_value, initiator):
     if old_value == symbol('NO_VALUE') or old_value == symbol('NEVER_SET'):
         old_value = None
     if offer.offer_id and value != old_value and old_value is not None:
         log = OfferLog(offer=offer)
         log.offer_id = offer.offer_id
         setattr(log, field, old_value)
         db.session.add(log)
         db.session.commit()
Пример #3
0
    def test_composites(self):
        sym1 = util.symbol('sym1', canonical=1)
        sym2 = util.symbol('sym2', canonical=2)
        sym3 = util.symbol('sym3', canonical=4)
        sym4 = util.symbol('sym4', canonical=8)

        assert sym1 & (sym2 | sym1 | sym4)
        assert not sym1 & (sym2 | sym3)

        assert not (sym1 | sym2) & (sym3 | sym4)
        assert (sym1 | sym2) & (sym2 | sym4)
Пример #4
0
def set_banner_fileUpload(target, value, oldvalue, initiator):
    """ Delete banner file when set

    This function is called every time the banner fileupload
    attribute is set. The function deletes the old image file
    when the fileupload attribute is set to a new value
    (a new image file is uploaded).
    
    """
    if oldvalue != symbol("NO_VALUE") and oldvalue != symbol("NEVER_SET") and value != oldvalue:
        os.remove(os.path.join(app.config["UPLOAD_FOLDER"], oldvalue))
Пример #5
0
    def test_basic(self):
        sym1 = util.symbol('foo')
        assert sym1.name == 'foo'
        sym2 = util.symbol('foo')

        assert sym1 is sym2
        assert sym1 == sym2

        sym3 = util.symbol('bar')
        assert sym1 is not sym3
        assert sym1 != sym3
Пример #6
0
    def test_pickle(self):
        sym1 = util.symbol('foo')
        sym2 = util.symbol('foo')

        assert sym1 is sym2

        # default
        s = util.pickle.dumps(sym1)
        sym3 = util.pickle.loads(s)

        for protocol in 0, 1, 2:
            print protocol
            serial = util.pickle.dumps(sym1)
            rt = util.pickle.loads(serial)
            assert rt is sym1
            assert rt is sym2
Пример #7
0
def _install_lookup_strategy(implementation):
    """Replace global class/object management functions
    with either faster or more comprehensive implementations,
    based on whether or not extended class instrumentation
    has been detected.

    This function is called only by InstrumentationRegistry()
    and unit tests specific to this behavior.

    """
    global instance_state, instance_dict, manager_of_class
    if implementation is util.symbol('native'):
        instance_state = attrgetter(ClassManager.STATE_ATTR)
        instance_dict = attrgetter("__dict__")
        def manager_of_class(cls):
            return cls.__dict__.get(ClassManager.MANAGER_ATTR, None)
    else:
        instance_state = instrumentation_registry.state_of
        instance_dict = instrumentation_registry.dict_of
        manager_of_class = instrumentation_registry.manager_of_class
    attributes.instance_state = instance_state
    attributes.instance_dict = instance_dict
    attributes.manager_of_class = manager_of_class
Пример #8
0
 def tearDownAll(self):
     clear_mappers()
     attributes._install_lookup_strategy(util.symbol('native'))
Пример #9
0
            return cls.__dict__.get(ClassManager.MANAGER_ATTR, None)
    else:
        instance_state = instrumentation_registry.state_of
        instance_dict = instrumentation_registry.dict_of
        manager_of_class = instrumentation_registry.manager_of_class
    attributes.instance_state = instance_state
    attributes.instance_dict = instance_dict
    attributes.manager_of_class = manager_of_class

_create_manager_for_cls = instrumentation_registry.create_manager_for_cls

# Install default "lookup" strategies.  These are basically
# very fast attrgetters for key attributes.
# When a custom ClassManager is installed, more expensive per-class
# strategies are copied over these.
_install_lookup_strategy(util.symbol('native'))


def find_native_user_instrumentation_hook(cls):
    """Find user-specified instrumentation management for a class."""
    return getattr(cls, INSTRUMENTATION_MANAGER, None)
instrumentation_finders.append(find_native_user_instrumentation_hook)

def _generate_init(class_, class_manager):
    """Build an __init__ decorator that triggers ClassManager events."""

    # TODO: we should use the ClassManager's notion of the 
    # original '__init__' method, once ClassManager is fixed
    # to always reference that.
    original__init__ = class_.__init__
    assert original__init__
Пример #10
0
    """

    # TODO: performance
    def __init__(comp):
        if isinstance(comp, dict):
            pass
        elif isinstance(comp, list):
            pass
        elif isinstance(comp, str):
            pass

    def apply(self, operation, target, *args, **kwargs):
        pass


COMPOSIVE_PROXY = util.symbol('COMPOSIVE_PROXY')


class ComposiveProxy(interfaces.InspectionAttrInfo):
    """A descriptor that presents a read/write view of an object attribute."""

    is_attribute = False
    extension_type = COMPOSIVE_PROXY

    def __init__(self, target_collection, composition):
        """
        """

        self.owning_class = None
        self.key = '_%s_%s_%s' % (type(self).__name__, target_collection,
                                  id(self))
Пример #11
0
    raise NotImplementedError()

def concat_op(a, b):
    return a.concat(b)

def desc_op(a):
    return a.desc()

def asc_op(a):
    return a.asc()

_commutative = set([eq, ne, add, mul])
def is_commutative(op):
    return op in _commutative

_smallest = symbol('_smallest')
_largest = symbol('_largest')

_PRECEDENCE = {
    from_: 15,
    mul: 7,
    div: 7,
    mod: 7,
    add: 6,
    sub: 6,
    concat_op: 6,
    match_op: 6,
    ilike_op: 5,
    notilike_op: 5,
    like_op: 5,
    notlike_op: 5,
Пример #12
0
# sqlalchemy/event.py
# Copyright (C) 2005-2013 the SQLAlchemy authors and contributors <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""Base event API."""

from sqlalchemy import util, exc
import weakref

CANCEL = util.symbol('CANCEL')
NO_RETVAL = util.symbol('NO_RETVAL')

def listen(target, identifier, fn, *args, **kw):
    """Register a listener function for the given target.

    e.g.::

        from sqlalchemy import event
        from sqlalchemy.schema import UniqueConstraint

        def unique_constraint_name(const, table):
            const.name = "uq_%s_%s" % (
                table.name,
                list(const.columns)[0].name
            )
        event.listen(
                UniqueConstraint,
                "after_parent_attach",
                unique_constraint_name)
Пример #13
0
    try:
        return proxies[module]
    except KeyError:
        return proxies.setdefault(module, _DBProxy(module, **params))

def clear_managers():
    """Remove all current DB-API 2.0 managers.

    All pools and connections are disposed.
    """

    for manager in proxies.itervalues():
        manager.close()
    proxies.clear()

reset_rollback = util.symbol('reset_rollback')
reset_commit = util.symbol('reset_commit')
reset_none = util.symbol('reset_none')


class Pool(log.Identified):
    """Abstract base class for connection pools."""

    def __init__(self,
                    creator, recycle=-1, echo=None,
                    use_threadlocal=False,
                    logging_name=None,
                    reset_on_return=True,
                    listeners=None,
                    events=None,
                    _dispatch=None):
Пример #14
0
def _is_hybrid_property(orm_descriptor):
    return orm_descriptor.extension_type == symbol('HYBRID_PROPERTY')
Пример #15
0
        return list(self)

    def __repr__(self):
        return repr(list(self))

    def __hash__(self):
        raise TypeError("%s objects are unhashable" % type(self).__name__)

    for func_name, func in list(locals().items()):
        if (util.callable(func) and func.__name__ == func_name
                and not func.__doc__ and hasattr(list, func_name)):
            func.__doc__ = getattr(list, func_name).__doc__
    del func_name, func


_NotProvided = util.symbol('_NotProvided')


class _AssociationDict(_AssociationCollection):
    """Generic, converting, dict-to-dict proxy."""
    def _create(self, key, value):
        return self.creator(key, value)

    def _get(self, object):
        return self.getter(object)

    def _set(self, object, key, value):
        return self.setter(object, key, value)

    def __getitem__(self, key):
        return self._get(self.col[key])
Пример #16
0
def nullslast_op(a):
    return a.nullslast()

_commutative = set([eq, ne, add, mul])

def is_commutative(op):
    return op in _commutative

def is_ordering_modifier(op):
    return op in (asc_op, desc_op, 
                    nullsfirst_op, nullslast_op)

_associative = _commutative.union([concat_op, and_, or_])


_smallest = symbol('_smallest')
_largest = symbol('_largest')

_PRECEDENCE = {
    from_: 15,
    mul: 7,
    truediv: 7,
    # Py2K
    div: 7,
    # end Py2K
    mod: 7,
    neg: 7,
    add: 6,
    sub: 6,
    concat_op: 6,
    match_op: 6,
Пример #17
0
def set_only_once(target, new_value, old_value, initiator):
    if old_value == new_value:
        return

    if old_value not in [None, symbol('NEVER_SET'), symbol('NO_VALUE')]:
        raise AttributeError("Attempted to set an immutable attribute")
Пример #18
0
This module is usually not directly visible to user applications, but
defines a large part of the ORM's interactivity.


"""

import operator
from operator import itemgetter

from sqlalchemy import util, event, exc as sa_exc
from sqlalchemy.orm import interfaces, collections, events

mapperutil = util.importlater("sqlalchemy.orm", "util")

PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT')
ATTR_WAS_SET = util.symbol('ATTR_WAS_SET')
ATTR_EMPTY = util.symbol('ATTR_EMPTY')
NO_VALUE = util.symbol('NO_VALUE')
NEVER_SET = util.symbol('NEVER_SET')

PASSIVE_RETURN_NEVER_SET = util.symbol(
    'PASSIVE_RETURN_NEVER_SET'
    """Symbol indicating that loader callables can be 
fired off, but if no callable is applicable and no value is
present, the attribute should remain non-initialized.
NEVER_SET is returned in this case.
""")

PASSIVE_NO_INITIALIZE = util.symbol(
    'PASSIVE_NO_INITIALIZE', """Symbol indicating that loader callables should
Пример #19
0
For more information on the PostgreSQL feature, see the
``ON CONFLICT` section of the `INSERT` statement in the PostgreSQL docs
<http://www.postgresql.org/docs/current/static/sql-insert.html#SQL-ON-CONFLICT>`_.
"""

import sqlalchemy.dialects.postgresql.base
from sqlalchemy.sql import compiler, expression, crud
from sqlalchemy import util
from sqlalchemy.sql.expression import ClauseElement, ColumnClause, ColumnElement
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.exc import CompileError
from sqlalchemy.schema import UniqueConstraint, PrimaryKeyConstraint, Index
from collections import Iterable

ISINSERT = util.symbol('ISINSERT')
ISUPDATE = util.symbol('ISUPDATE')
ISDELETE = util.symbol('ISDELETE')

def _setup_crud_params(compiler, stmt, local_stmt_type, **kw):
	restore_isinsert = compiler.isinsert
	restore_isupdate = compiler.isupdate
	restore_isdelete = compiler.isdelete

	should_restore = (
		restore_isinsert or restore_isupdate or restore_isdelete
	) or len(compiler.stack) > 1

	if local_stmt_type is ISINSERT:
		compiler.isupdate = False
		compiler.isinsert = True
Пример #20
0
        # Replace __init__(), feed defaults
        original_init = cls.__init__

        def __init__(self, /, **values):
            return original_init(self, **{**defaults, **values})
        cls.__init__ = __init__

        # Done
        return cls

    return wrapper


def dataclass_notset(*names):
    """ Set a default NOTSET value for a dataclass with __slots__

    Example:
        @dataclass_notset('key')
        @dataclass
        class Object:
            key: str
    """
    return dataclass_defaults(**{
        name: NOTSET
        for name in names
    })


# Marker for values not yet set
NOTSET = symbol('NOTSET')
Пример #21
0
def unit_set(target, value, oldvalue, initiator):
    """ Listen for the unit 'set' event and convert target's value when the new unit is different/"""
    if (oldvalue != symbol('NO_VALUE')) and (oldvalue != value):
        target.value = (target.value*oldvalue).to(value).value
Пример #22
0
def _is_hybrid_method(orm_descriptor):
    return orm_descriptor.extension_type == symbol('HYBRID_METHOD')
Пример #23
0
def set_only_once(target, new_value, old_value, initiator):
    if old_value == new_value:
        return

    if old_value not in [None, symbol('NEVER_SET'), symbol('NO_VALUE')]:
        raise AttributeError("Attempted to set an immutable attribute")
Пример #24
0
 def teardown_class(cls):
     clear_mappers()
     attributes._install_lookup_strategy(util.symbol('native'))
Пример #25
0
# attributes.py - manages object attributes
# Copyright (C) 2005, 2006, 2007, 2008 Michael Bayer [email protected]
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

import operator, weakref
from itertools import chain
import UserDict
from sqlalchemy import util
from sqlalchemy.orm import interfaces, collections
from sqlalchemy.orm.util import identity_equal
from sqlalchemy import exceptions

PASSIVE_NORESULT = util.symbol("PASSIVE_NORESULT")
ATTR_WAS_SET = util.symbol("ATTR_WAS_SET")
NO_VALUE = util.symbol("NO_VALUE")
NEVER_SET = util.symbol("NEVER_SET")


class InstrumentedAttribute(interfaces.PropComparator):
    """public-facing instrumented attribute, placed in the
    class dictionary.

    """

    def __init__(self, impl, comparator=None):
        """Construct an InstrumentedAttribute.
        comparator
          a sql.Comparator to which class-level compare/math events will be sent
        """
Пример #26
0
# sqlalchemy/event.py
# Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
"""Base event API."""

from sqlalchemy import util, exc

CANCEL = util.symbol('CANCEL')
NO_RETVAL = util.symbol('NO_RETVAL')


def listen(target, identifier, fn, *args, **kw):
    """Register a listener function for the given target.

    e.g.::

        from sqlalchemy import event
        from sqlalchemy.schema import UniqueConstraint

        def unique_constraint_name(const, table):
            const.name = "uq_%s_%s" % (
                table.name,
                list(const.columns)[0].name
            )
        event.listen(
                UniqueConstraint,
                "after_parent_attach",
                unique_constraint_name)
Пример #27
0
    "EXT_STOP",
    "ExtensionOption",
    "InstrumentationManager",
    "LoaderStrategy",
    "MapperExtension",
    "MapperOption",
    "MapperProperty",
    "PropComparator",
    "PropertyOption",
    "SessionExtension",
    "StrategizedOption",
    "StrategizedProperty",
    "build_path",
)

EXT_CONTINUE = util.symbol("EXT_CONTINUE")
EXT_STOP = util.symbol("EXT_STOP")

ONETOMANY = util.symbol("ONETOMANY")
MANYTOONE = util.symbol("MANYTOONE")
MANYTOMANY = util.symbol("MANYTOMANY")


class MapperExtension(object):
    """Base implementation for customizing ``Mapper`` behavior.
    
    New extension classes subclass ``MapperExtension`` and are specified
    using the ``extension`` mapper() argument, which is a single
    ``MapperExtension`` or a list of such.   A single mapper
    can maintain a chain of ``MapperExtension`` objects.  When a
    particular mapping event occurs, the corresponding method 
Пример #28
0
    else:
        instance_state = instrumentation_registry.state_of
        instance_dict = instrumentation_registry.dict_of
        manager_of_class = instrumentation_registry.manager_of_class
    attributes.instance_state = instance_state
    attributes.instance_dict = instance_dict
    attributes.manager_of_class = manager_of_class


_create_manager_for_cls = instrumentation_registry.create_manager_for_cls

# Install default "lookup" strategies.  These are basically
# very fast attrgetters for key attributes.
# When a custom ClassManager is installed, more expensive per-class
# strategies are copied over these.
_install_lookup_strategy(util.symbol('native'))


def find_native_user_instrumentation_hook(cls):
    """Find user-specified instrumentation management for a class."""
    return getattr(cls, INSTRUMENTATION_MANAGER, None)


instrumentation_finders.append(find_native_user_instrumentation_hook)


def _generate_init(class_, class_manager):
    """Build an __init__ decorator that triggers ClassManager events."""

    # TODO: we should use the ClassManager's notion of the
    # original '__init__' method, once ClassManager is fixed
Пример #29
0
_commutative = set([eq, ne, add, mul])


def is_commutative(op):
    return op in _commutative


def is_ordering_modifier(op):
    return op in (asc_op, desc_op, nullsfirst_op, nullslast_op)


_associative = _commutative.union([concat_op, and_, or_])


_smallest = symbol("_smallest")
_largest = symbol("_largest")

_PRECEDENCE = {
    from_: 15,
    mul: 7,
    truediv: 7,
    # Py2K
    div: 7,
    # end Py2K
    mod: 7,
    neg: 7,
    add: 6,
    sub: 6,
    concat_op: 6,
    match_op: 6,
Пример #30
0
 def teardown_class(cls):
     clear_mappers()
     instrumentation._install_lookup_strategy(util.symbol('native'))
Пример #31
0
 def tearDownAll(self):
     clear_mappers()
     attributes._install_lookup_strategy(util.symbol('native'))
Пример #32
0
def parse_select(d):
    """
        Defintion of a select query according to
        http://www.postgresql.org/docs/9.3/static/sql-select.html

        not implemented:
            [ WITH [ RECURSIVE ] with_query [, ...] ]
            [ WINDOW window_name AS ( window_definition ) [, ...] ]
            [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]
    """
    distinct = d.get('distinct', False)

    L = None

    keyword = d.get('keyword')

    if keyword and keyword.lower() in ['union', 'except', 'intersect']:
        partials = []
        for part_sel in d.get('selects', []):
            t = part_sel.get('type')
            if t == 'grouping':
                grouping = get_or_403(part_sel, 'grouping')
                if isinstance(grouping, dict):
                    partials.append(parse_select(grouping))
                elif isinstance(grouping, list):
                    partials = map(parse_select, grouping)
                else:
                    APIError(
                        'Cannot handle grouping type. Dictionary or list expected.'
                    )
            elif t == 'select':
                partials.append(parse_select(part_sel))
            else:
                raise APIError('Unknown select type: ' + t)
        query = CompoundSelect(util.symbol(keyword), *partials)
    else:
        kwargs = dict(distinct=distinct)
        if 'fields' in d and d['fields']:
            L = []
            for field in d['fields']:
                col = parse_expression(field)
                if 'as' in field:
                    col.label(read_pgid(field['as']))
                L.append(col)
        if 'from' in d:
            kwargs['from_obj'] = parse_from_item(get_or_403(d, 'from'))
        else:
            kwargs['from_obj'] = []
        if not L:
            L = '*'
        kwargs['columns'] = L
        query = select(**kwargs)

        # [ WHERE condition ]
        if d.get('where', False):
            query = query.where(parse_condition(d['where']))

    if 'group_by' in d:
        query = query.group_by(*[parse_expression(f) for f in d['group_by']])

    if 'having' in d:
        query.having([parse_condition(f) for f in d['having']])

    if 'select' in d:
        for constraint in d['select']:
            type = get_or_403(constraint, 'type')
            subquery = parse_select(get_or_403(constraint, 'query'))
            if type.lower() == 'union':
                query.union(subquery)
            elif type.lower() == 'intersect':
                query.intersect(subquery)
            elif type.lower() == 'except':
                query.except_(subquery)
    if 'order_by' in d:
        for ob in d['order_by']:
            expr = parse_expression(ob)
            if isinstance(ob, dict):
                desc = ob.get('ordering', 'asc').lower() == 'desc'
                if desc:
                    expr = expr.desc()
            query = query.order_by(expr)

    if 'limit' in d:
        if isinstance(d['limit'], int) or d['limit'].isdigit():
            query = query.limit(int(d['limit']))
        else:
            raise APIError('Invalid LIMIT: Expected a digit')

    if 'offset' in d:
        if isinstance(d['offset'], int) or d['offset'].isdigit():
            query = query.offset(int(d['offset']))
        else:
            raise APIError('Invalid LIMIT: Expected a digit')
    return query
        return list(self)

    def __repr__(self):
        return repr(list(self))

    def __hash__(self):
        raise TypeError("%s objects are unhashable" % type(self).__name__)

    for func_name, func in list(locals().items()):
        if (util.callable(func) and func.__name__ == func_name and
            not func.__doc__ and hasattr(list, func_name)):
            func.__doc__ = getattr(list, func_name).__doc__
    del func_name, func


_NotProvided = util.symbol('_NotProvided')
class _AssociationDict(_AssociationCollection):
    """Generic, converting, dict-to-dict proxy."""

    def _create(self, key, value):
        return self.creator(key, value)

    def _get(self, object):
        return self.getter(object)

    def _set(self, object, key, value):
        return self.setter(object, key, value)

    def __getitem__(self, key):
        return self._get(self.col[key])
Пример #34
0
# sqlalchemy/event.py
# Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""Base event API."""

from sqlalchemy import util, exc

CANCEL = util.symbol("CANCEL")
NO_RETVAL = util.symbol("NO_RETVAL")


def listen(target, identifier, fn, *args, **kw):
    """Register a listener function for the given target.
    
    e.g.::
    
        from sqlalchemy import event
        from sqlalchemy.schema import UniqueConstraint
        
        def unique_constraint_name(const, table):
            const.name = "uq_%s_%s" % (
                table.name,
                list(const.columns)[0].name
            )
        event.listen(
                UniqueConstraint, 
                "after_parent_attach", 
                unique_constraint_name)
Пример #35
0
This module is usually not directly visible to user applications, but
defines a large part of the ORM's interactivity.


"""

import operator
from operator import itemgetter

from sqlalchemy import util, event, exc as sa_exc
from sqlalchemy.orm import interfaces, collections, events


mapperutil = util.importlater("sqlalchemy.orm", "util")

PASSIVE_NO_RESULT = util.symbol('PASSIVE_NO_RESULT')
ATTR_WAS_SET = util.symbol('ATTR_WAS_SET')
ATTR_EMPTY = util.symbol('ATTR_EMPTY')
NO_VALUE = util.symbol('NO_VALUE')
NEVER_SET = util.symbol('NEVER_SET')

PASSIVE_RETURN_NEVER_SET = util.symbol('PASSIVE_RETURN_NEVER_SET'
"""Symbol indicating that loader callables can be 
fired off, but if no callable is applicable and no value is
present, the attribute should remain non-initialized.
NEVER_SET is returned in this case.
""")

PASSIVE_NO_INITIALIZE = util.symbol('PASSIVE_NO_INITIALIZE',
"""Symbol indicating that loader callables should
   not be fired off, and a non-initialized attribute 
Пример #36
0
def parse_select(d):
    """
        Defintion of a select query according to
        http://www.postgresql.org/docs/9.3/static/sql-select.html

        not implemented:
            [ WITH [ RECURSIVE ] with_query [, ...] ]
            [ WINDOW window_name AS ( window_definition ) [, ...] ]
            [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]
    """
    distinct = d.get("distinct", False)

    L = None

    keyword = d.get("keyword")

    if keyword and keyword.lower() in ["union", "except", "intersect"]:
        partials = []
        for part_sel in d.get("selects", []):
            t = part_sel.get("type")
            if t == "grouping":
                grouping = get_or_403(part_sel, "grouping")
                if isinstance(grouping, dict):
                    partials.append(parse_select(grouping))
                elif isinstance(grouping, list):
                    partials = map(parse_select, grouping)
                else:
                    APIError(
                        "Cannot handle grouping type. Dictionary or list expected."
                    )
            elif t == "select":
                partials.append(parse_select(part_sel))
            else:
                raise APIError("Unknown select type: " + t)
        query = CompoundSelect(util.symbol(keyword), *partials)
    else:
        kwargs = dict(distinct=distinct)
        if "fields" in d and d["fields"]:
            L = []
            for field in d["fields"]:
                if isinstance(field, str):
                    field = dict(type="column", column=field)
                col = parse_expression(field)
                if "as" in field:
                    col.label(read_pgid(field["as"]))
                L.append(col)
        if "from" in d:
            kwargs["from_obj"] = parse_from_item(get_or_403(d, "from"))
        else:
            kwargs["from_obj"] = []
        if not L:
            L = "*"
        kwargs["columns"] = L
        query = select(**kwargs)

        # [ WHERE condition ]
        if d.get("where", False):
            query = query.where(parse_condition(d["where"]))

    if "group_by" in d:
        query = query.group_by(*[parse_expression(f) for f in d["group_by"]])

    if "having" in d:
        query.having([parse_condition(f) for f in d["having"]])

    if "select" in d:
        for constraint in d["select"]:
            type = get_or_403(constraint, "type")
            subquery = parse_select(get_or_403(constraint, "query"))
            if type.lower() == "union":
                query.union(subquery)
            elif type.lower() == "intersect":
                query.intersect(subquery)
            elif type.lower() == "except":
                query.except_(subquery)
    if "order_by" in d:
        for ob in d["order_by"]:
            expr = parse_expression(ob)
            if isinstance(ob, dict):
                desc = ob.get("ordering", "asc").lower() == "desc"
                if desc:
                    expr = expr.desc()
            query = query.order_by(expr)

    if "limit" in d:
        if isinstance(d["limit"], int) or d["limit"].isdigit():
            query = query.limit(int(d["limit"]))
        else:
            raise APIError("Invalid LIMIT: Expected a digit")

    if "offset" in d:
        if isinstance(d["offset"], int) or d["offset"].isdigit():
            query = query.offset(int(d["offset"]))
        else:
            raise APIError("Invalid LIMIT: Expected a digit")
    return query
Пример #37
0
def _dict_decorators():
    """Tailored instrumentation wrappers for any dict-like mapping class."""

    def _tidy(fn):
        setattr(fn, '_sa_instrumented', True)
        fn.__doc__ = getattr(getattr(dict, fn.__name__), '__doc__')

    Unspecified = util.symbol('Unspecified')

    def __setitem__(fn):
        def __setitem__(self, key, value, _sa_initiator=None):
            if key in self:
                __del(self, self[key], _sa_initiator)
            value = __set(self, value, _sa_initiator)
            fn(self, key, value)
        _tidy(__setitem__)
        return __setitem__

    def __delitem__(fn):
        def __delitem__(self, key, _sa_initiator=None):
            if key in self:
                __del(self, self[key], _sa_initiator)
            fn(self, key)
        _tidy(__delitem__)
        return __delitem__

    def clear(fn):
        def clear(self):
            for key in self:
                __del(self, self[key])
            fn(self)
        _tidy(clear)
        return clear

    def pop(fn):
        def pop(self, key, default=Unspecified):
            if key in self:
                __del(self, self[key])
            if default is Unspecified:
                return fn(self, key)
            else:
                return fn(self, key, default)
        _tidy(pop)
        return pop

    def popitem(fn):
        def popitem(self):
            __before_delete(self)
            item = fn(self)
            __del(self, item[1])
            return item
        _tidy(popitem)
        return popitem

    def setdefault(fn):
        def setdefault(self, key, default=None):
            if key not in self:
                self.__setitem__(key, default)
                return default
            else:
                return self.__getitem__(key)
        _tidy(setdefault)
        return setdefault

    if sys.version_info < (2, 4):
        def update(fn):
            def update(self, other):
                for key in other.keys():
                    if key not in self or self[key] is not other[key]:
                        self[key] = other[key]
            _tidy(update)
            return update
    else:
        def update(fn):
            def update(self, __other=Unspecified, **kw):
                if __other is not Unspecified:
                    if hasattr(__other, 'keys'):
                        for key in __other.keys():
                            if (key not in self or
                                self[key] is not __other[key]):
                                self[key] = __other[key]
                    else:
                        for key, value in __other:
                            if key not in self or self[key] is not value:
                                self[key] = value
                for key in kw:
                    if key not in self or self[key] is not kw[key]:
                        self[key] = kw[key]
            _tidy(update)
            return update

    l = locals().copy()
    l.pop('_tidy')
    l.pop('Unspecified')
    return l
Пример #38
0
    except KeyError:
        return proxies.setdefault(module, _DBProxy(module, **params))


def clear_managers():
    """Remove all current DB-API 2.0 managers.

    All pools and connections are disposed.
    """

    for manager in proxies.itervalues():
        manager.close()
    proxies.clear()


reset_rollback = util.symbol('reset_rollback')
reset_commit = util.symbol('reset_commit')
reset_none = util.symbol('reset_none')


class Pool(log.Identified):
    """Abstract base class for connection pools."""
    def __init__(self,
                 creator,
                 recycle=-1,
                 echo=None,
                 use_threadlocal=False,
                 logging_name=None,
                 reset_on_return=True,
                 listeners=None,
                 events=None,
Пример #39
0
def _set_decorators():
    """Tailored instrumentation wrappers for any set-like class."""

    def _tidy(fn):
        setattr(fn, '_sa_instrumented', True)
        fn.__doc__ = getattr(getattr(set, fn.__name__), '__doc__')

    Unspecified = util.symbol('Unspecified')

    def add(fn):
        def add(self, value, _sa_initiator=None):
            if value not in self:
                value = __set(self, value, _sa_initiator)
            # testlib.pragma exempt:__hash__
            fn(self, value)
        _tidy(add)
        return add

    if sys.version_info < (2, 4):
        def discard(fn):
            def discard(self, value, _sa_initiator=None):
                if value in self:
                    self.remove(value, _sa_initiator)
            _tidy(discard)
            return discard
    else:
        def discard(fn):
            def discard(self, value, _sa_initiator=None):
                # testlib.pragma exempt:__hash__
                if value in self:
                    __del(self, value, _sa_initiator)
                    # testlib.pragma exempt:__hash__
                fn(self, value)
            _tidy(discard)
            return discard

    def remove(fn):
        def remove(self, value, _sa_initiator=None):
            # testlib.pragma exempt:__hash__
            if value in self:
                __del(self, value, _sa_initiator)
            # testlib.pragma exempt:__hash__
            fn(self, value)
        _tidy(remove)
        return remove

    def pop(fn):
        def pop(self):
            __before_delete(self)
            item = fn(self)
            __del(self, item)
            return item
        _tidy(pop)
        return pop

    def clear(fn):
        def clear(self):
            for item in list(self):
                self.remove(item)
        _tidy(clear)
        return clear

    def update(fn):
        def update(self, value):
            for item in value:
                self.add(item)
        _tidy(update)
        return update

    def __ior__(fn):
        def __ior__(self, value):
            if not _set_binops_check_strict(self, value):
                return NotImplemented
            for item in value:
                self.add(item)
            return self
        _tidy(__ior__)
        return __ior__

    def difference_update(fn):
        def difference_update(self, value):
            for item in value:
                self.discard(item)
        _tidy(difference_update)
        return difference_update

    def __isub__(fn):
        def __isub__(self, value):
            if not _set_binops_check_strict(self, value):
                return NotImplemented
            for item in value:
                self.discard(item)
            return self
        _tidy(__isub__)
        return __isub__

    def intersection_update(fn):
        def intersection_update(self, other):
            want, have = self.intersection(other), set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
        _tidy(intersection_update)
        return intersection_update

    def __iand__(fn):
        def __iand__(self, other):
            if not _set_binops_check_strict(self, other):
                return NotImplemented
            want, have = self.intersection(other), set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
        _tidy(__iand__)
        return __iand__

    def symmetric_difference_update(fn):
        def symmetric_difference_update(self, other):
            want, have = self.symmetric_difference(other), set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
        _tidy(symmetric_difference_update)
        return symmetric_difference_update

    def __ixor__(fn):
        def __ixor__(self, other):
            if not _set_binops_check_strict(self, other):
                return NotImplemented
            want, have = self.symmetric_difference(other), set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
        _tidy(__ixor__)
        return __ixor__

    l = locals().copy()
    l.pop('_tidy')
    l.pop('Unspecified')
    return l
 def teardown_class(cls):
     clear_mappers()
     instrumentation._install_lookup_strategy(util.symbol('native'))
Пример #41
0
# attributes.py - manages object attributes
# Copyright (C) 2005, 2006, 2007, 2008 Michael Bayer [email protected]
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

import operator, weakref
from itertools import chain
import UserDict
from sqlalchemy import util
from sqlalchemy.orm import interfaces, collections
from sqlalchemy.orm.util import identity_equal
from sqlalchemy import exceptions

PASSIVE_NORESULT = util.symbol('PASSIVE_NORESULT')
ATTR_WAS_SET = util.symbol('ATTR_WAS_SET')
NO_VALUE = util.symbol('NO_VALUE')
NEVER_SET = util.symbol('NEVER_SET')

class InstrumentedAttribute(interfaces.PropComparator):
    """public-facing instrumented attribute, placed in the
    class dictionary.

    """

    def __init__(self, impl, comparator=None):
        """Construct an InstrumentedAttribute.
        comparator
          a sql.Comparator to which class-level compare/math events will be sent
        """
Пример #42
0
    'EXT_STOP',
    'ExtensionOption',
    'InstrumentationManager',
    'LoaderStrategy',
    'MapperExtension',
    'MapperOption',
    'MapperProperty',
    'PropComparator',
    'PropertyOption',
    'SessionExtension',
    'StrategizedOption',
    'StrategizedProperty',
    'build_path',
)

EXT_CONTINUE = util.symbol('EXT_CONTINUE')
EXT_STOP = util.symbol('EXT_STOP')

ONETOMANY = util.symbol('ONETOMANY')
MANYTOONE = util.symbol('MANYTOONE')
MANYTOMANY = util.symbol('MANYTOMANY')

from .deprecated_interfaces import AttributeExtension, SessionExtension, \
    MapperExtension


class MapperProperty(object):
    """Manage the relationship of a ``Mapper`` to a single class
    attribute, as well as that attribute as it appears on individual
    instances of the class, including attribute instrumentation,
    attribute access, loading behavior, and dependency calculations.
Пример #43
0
    'EXT_STOP',
    'ExtensionOption',
    'InstrumentationManager',
    'LoaderStrategy',
    'MapperExtension',
    'MapperOption',
    'MapperProperty',
    'PropComparator',
    'PropertyOption',
    'SessionExtension',
    'StrategizedOption',
    'StrategizedProperty',
    'build_path',
    )

EXT_CONTINUE = util.symbol('EXT_CONTINUE')
EXT_STOP = util.symbol('EXT_STOP')

ONETOMANY = util.symbol('ONETOMANY')
MANYTOONE = util.symbol('MANYTOONE')
MANYTOMANY = util.symbol('MANYTOMANY')

class MapperExtension(object):
    """Base implementation for customizing ``Mapper`` behavior.

    New extension classes subclass ``MapperExtension`` and are specified
    using the ``extension`` mapper() argument, which is a single
    ``MapperExtension`` or a list of such.   A single mapper
    can maintain a chain of ``MapperExtension`` objects.  When a
    particular mapping event occurs, the corresponding method 
    on each ``MapperExtension`` is invoked serially, and each method
Пример #44
0
    def copy(self):
        return list(self)

    def __repr__(self):
        return repr(list(self))

    def __hash__(self):
        raise TypeError("%s objects are unhashable" % type(self).__name__)

    for func_name, func in locals().items():
        if util.callable(func) and func.func_name == func_name and not func.__doc__ and hasattr(list, func_name):
            func.__doc__ = getattr(list, func_name).__doc__
    del func_name, func


_NotProvided = util.symbol("_NotProvided")


class _AssociationDict(_AssociationCollection):
    """Generic, converting, dict-to-dict proxy."""

    def _create(self, key, value):
        return self.creator(key, value)

    def _get(self, object):
        return self.getter(object)

    def _set(self, object, key, value):
        return self.setter(object, key, value)

    def __getitem__(self, key):
Пример #45
0
 def teardown_class(cls):
     clear_mappers()
     attributes._install_lookup_strategy(util.symbol('native'))
Пример #46
0
from sqlalchemy.orm.attributes import InstrumentedAttribute, QueryableAttribute
from sqlalchemy.orm.base import InspectionAttr, MANYTOMANY, MANYTOONE, ONETOMANY
from sqlalchemy.orm.dynamic import DynaLoader
from sqlalchemy.sql import ColumnElement, Selectable
from sqlalchemy.sql.elements import Label
from sqlalchemy.sql.type_api import TypeEngine
from sqlalchemy.util import symbol

from sa2schema import SAAttributeType
from sa2schema.compat import Literal, get_args, get_origin
from sa2schema.util import get_deep_subclasses
from .defs import AttributeType
from .property import get_property_loads_attribute_names

# Value not provided (e.g. `default` value)
NOT_PROVIDED = symbol('NOT_PROVIDED')

# AttributeInfo type variable
Info_T = TypeVar('Info_T')


@dataclass
class AttributeInfo:
    """ Information about an SqlAlchemy attribute. Base class."""
    # To support new properties on SqlAlchemy models, just implement another class.
    # If the extracted type is unsatisfactory, it can be overridden with annotations.

    # Attribute type
    attribute_type: AttributeType

    # Attribute itself