Exemple #1
0
class WorkflowMeta(MappingSchema):
    """Data structure to define a workflow (finite state machine)."""

    initial_state = SingleLine(missing=required)
    states = SchemaNode(Mapping(unknown='preserve'),
                        missing=required)
    transitions = SchemaNode(Mapping(unknown='preserve'),
                             missing=required)
Exemple #2
0
 def __init__(self, *args, **kwargs):
     super(DefinitionSchema, self).__init__(Mapping(), *args, **kwargs)
     self.add(SchemaNode(String(), name='title'))
     self.add(SchemaNode(String(), name='description'))
     self.add(
         SchemaNode(Mapping(unknown="preserve"), name="extra",
                    missing=drop))
     self.add(
         SchemaNode(Sequence(),
                    SchemaNode(TypeFieldNode()),
                    name='fields',
                    validator=Length(min=1)))
Exemple #3
0
def convert_types(mapping, row):
    """ Translate a row of input data (e.g. from a CSV file) into the
    structure understood by the dataset loader, i.e. where all 
    dimensions are dicts and all types have been converted. 

    This will validate the incoming data and emit a colander.Invalid
    exception if validation was unsuccessful."""
    out = {}
    errors = Invalid(SchemaNode(Mapping(unknown='preserve')))

    for dimension, meta in mapping.items():
        meta['dimension'] = dimension

        # handle AttributeDimensions, Measures and DateDimensions.
        # this is clever, but possibly not always true.
        if 'column' in meta and meta['type'] not in ('compound', 'geometry'):
            try:
                out[dimension] = _cast(row, meta, dimension)
            except Invalid, i:
                errors.add(i)

        # handle CompoundDimensions.
        else:
            out[dimension] = {}

            for attribute, ameta in meta.get('attributes', {}).items():
                try:
                    out[dimension][attribute] = \
                            _cast(row, ameta, dimension + '.' +
                                    attribute)
                except Invalid, i:
                    errors.add(i)
Exemple #4
0
    def definition(cls, **kwargs):
        schema = SchemaNode(Mapping(unknown="preserve"))

        schema.add(SchemaNode(String(), name='label', missing=u''))
        schema.add(
            SchemaNode(String(), name='type', validator=OneOf(["annotation"])))
        return schema
Exemple #5
0
 def definition(cls):
     schema = SchemaNode(Mapping())
     schema.add(SchemaNode(String(), name='name'))
     schema.add(SchemaNode(String(), name='description'))
     schema.add(
         SchemaNode(String(), name='type', validator=OneOf(types.names)))
     return schema
Exemple #6
0
    def __init__(self, class_, includes=None, excludes=None, overrides=None, unknown='ignore', nested=False, type_overrides=None, relationship_overrides=None, automatic_relationships=False, **kw):
        """
        :param includes:
        :param overrides:
        :param unknown:
        :param type_overrides: callable(name, column, column_type)
        :param automatic_relationships: Only follow relationships if they are on include list
        :param kw:
        :return:
        """
        assert type_overrides, "Always provide type_overrides, otherwise this crap doesn't work when these nodes get nested"

        self.inspector = inspect(class_)
        kwargs = kw.copy()

        # Obtain configuration specific from the mapped class
        kwargs.update(getattr(self.inspector.class_, self.ca_class_key, {}))
        unknown = kwargs.pop('unknown', unknown)

        # The default type of this SchemaNode is Mapping.
        super(SQLAlchemySchemaNode, self).__init__(Mapping(unknown), **kwargs)
        self.class_ = class_
        self.includes = includes or {}
        self.excludes = excludes or {}
        self.overrides = overrides or {}
        self.unknown = unknown
        self.declarative_overrides = {}
        self.kwargs = kwargs or {}
        self.type_overrides = type_overrides
        self.relationship_overrides = relationship_overrides
        self.nested = nested
        self.automatic_relationships = automatic_relationships
        self.add_nodes(self.includes, self.excludes, self.overrides, nested)
Exemple #7
0
def ballot_voting_form(ballot_voting, request):

    yes_no_choices = [(True, _('Yes')), (False, _('No')), (None, _('Abstention'))]
    max_points = 9 if len(ballot_voting.options) > 3 else 3
    point_choices = [(i, str(i)) for i in range(max_points+1)]

    schema = Schema()

    for option in ballot_voting.options:

        option_schema = SchemaNode(Mapping(), name=str(option.uuid), title=option.title)

        option_schema.add(SchemaNode(
            Boolean(),
            validator=OneOf([x[0] for x in yes_no_choices]),
            widget=RadioChoiceWidget(values=yes_no_choices, inline=True),
            name='yes_no',
            title=f'Stimmst du dem Antrag zu?'))

        option_schema.add(SchemaNode(
            Int(),
            validator=OneOf([x[0] for x in point_choices]),
            widget=RadioChoiceWidget(values=point_choices, inline=True, null_value='0'),
            name='points',
            title='Welche Punktzahl gibst du dem Antrag?',
            missing=0))

        schema.add(option_schema)

    form = Form(schema, request, buttons=[Button(title=_('check'))])
    return form
Exemple #8
0
 def test_widget_no_maker_with_default_widget_maker(self):
     from deform.widget import MappingWidget
     from colander import Mapping
     schema = DummySchema()
     schema.typ = Mapping()
     field = self._makeOne(schema)
     widget = field.widget
     self.assertEqual(widget.__class__, MappingWidget)
Exemple #9
0
def _add_captcha(geo_form_schema, schema):
    schema = schema.clone()
    schema.add(SchemaNode(
        Mapping(),
        name='captcha',
        widget=RecaptchaWidget(
            public_key=geo_form_schema.recaptcha_public_key,
            private_key=geo_form_schema.recaptcha_private_key)))
    return schema
Exemple #10
0
 def __init__(self):
     super(DefinitionValidator, self).__init__(Mapping())
     self.add(SchemaNode(String(), name='title'))
     self.add(SchemaNode(String(), name='description'))
     self.add(
         SchemaNode(Sequence(),
                    SchemaNode(TypeFieldNode()),
                    name='fields',
                    validator=Length(min=1)))
Exemple #11
0
 def __init__(self, definition, *args, **kwargs):
     kwargs.setdefault('typ', Mapping())
     super(RecordSchema, self).__init__(*args, **kwargs)
     definition = deepcopy(definition)
     for field in definition['fields']:
         field['root'] = self
         fieldtype = field.pop('type')
         schema = registry.validation(fieldtype, **field)
         if schema:
             self.add(schema)
Exemple #12
0
    def definition(cls, **kwargs):
        schema = SchemaNode(Mapping(unknown="preserve"))

        if kwargs.get('named', True):
            schema.add(
                SchemaNode(String(),
                           name='name',
                           validator=Regex(r'^[a-zA-Z][a-zA-Z0-9_\-]*$')))

        schema.add(SchemaNode(String(), name='label', missing=u''))
        schema.add(SchemaNode(String(), name='hint', missing=cls.hint))
        schema.add(SchemaNode(Boolean(), name='required',
                              missing=cls.required))
        schema.add(
            SchemaNode(String(), name='type', validator=OneOf(registry.names)))
        return schema
Exemple #13
0
def validator_from_model(model):
    validator = Schema(Mapping())
    for key, column in model.__table__.columns.items():
        if key in _excludes:
            # skip things like ID that won't be in the body
            continue
        missing = colander.required
        if column.nullable:
            missing = colander.drop
        validator.add(
            SchemaNode(sqla_to_colander_type(column.type),
                       name=key,
                       missing=missing,
                       **sqla_kwargs(column.type)))

    return CorniceSchema.from_colander(validator)
Exemple #14
0
 def schema_type(self):
     return Mapping()
Exemple #15
0
 def __init__(self, *args, **kwargs):
     super(PermissionsSchema, self).__init__(Mapping(unknown='preserve'),
                                             *args, **kwargs)
Exemple #16
0
class BBoxWidget(Widget):
    """
    Renders a BoundingBox Widget.

    **Attributes/Arguments**
    template
        The template name used to render the input widget.  Default:
        ``bbox``.
    readonly_template
        The template name used to render the widget in read-only mode.
        Default: ``readonly/bbox``.
    """
    template = 'bbox'
    readonly_template = 'readonly/bbox'

    _pstruct_schema = SchemaNode(
        Mapping(),
        SchemaNode(_StrippedString(), name='minx'),
        SchemaNode(_StrippedString(), name='miny'),
        SchemaNode(_StrippedString(), name='maxx'),
        SchemaNode(_StrippedString(), name='maxy'))

    def serialize(self, field, cstruct, **kw):
        if cstruct is null:
            minx = '-180'
            miny = '-90'
            maxx = '180'
            maxy = '90'
        else:
            minx, miny, maxx, maxy = cstruct.split(',', 3)

        kw.setdefault('minx', minx)
        kw.setdefault('miny', miny)
        kw.setdefault('maxx', maxx)
        kw.setdefault('maxy', maxy)

        # readonly = kw.get('readonly', self.readonly)
        # TODO: add readonly template
        readonly = False
        template = readonly and self.readonly_template or self.template
        values = self.get_template_values(field, cstruct, kw)
        return field.renderer(template, **values)

    def deserialize(self, field, pstruct):
        if pstruct is null:
            return null
        else:
            try:
                validated = self._pstruct_schema.deserialize(pstruct)
            except Invalid as exc:
                raise Invalid(field.schema, text_("Invalid pstruct: %s" % exc))
            minx = validated['minx']
            miny = validated['miny']
            maxx = validated['maxx']
            maxy = validated['maxy']

            if not minx and not minx and not maxx and not maxy:
                return null

            result = ','.join([minx, miny, maxx, maxy])

            if not minx or not miny or not maxx or not maxy:
                raise Invalid(field.schema, 'Incomplete bbox', result)

            return result
Exemple #17
0
    def get_schema_from_relationship(self, prop: RelationshipProperty,
                                     overrides: dict) -> SchemaNode:
        """Build and return a :class:`colander.SchemaNode` for a relationship.

        The mapping process will translate one-to-many and many-to-many
        relationships from SQLAlchemy into a ``Sequence`` of ``Mapping`` nodes
        in Colander, and translate one-to-one and many-to-one relationships
        into a ``Mapping`` node in Colander.  The related class involved in the
        relationship will be recursively mapped by ColanderAlchemy as part of
        this process, following the same mapping process.

        This method uses information stored in the relationship within
        the ``info`` that was passed to the relationship on creation.
        This means that ``Colander`` options can be specified
        declaratively in ``SQLAlchemy`` models using the ``info``
        argument that you can pass to
        :meth:`sqlalchemy.orm.relationship`.

        For all relationships, the settings will only be applied to the outer
        Sequence or Mapping. To customise the inner schema node, create the
        attribute ``__colanderalchemy_config__`` on the related model with a
        dict-like structure corresponding to the Colander options that should
        be customised.

        Arguments/Keywords

        :param prop: RelationshipProperty
        :param overrides: Dictionary with attributes to be overriden.
        :return: SchemaNode instance.
        """
        # The name of the SchemaNode is the ColumnProperty key.
        name = self._change_name(prop)
        kwargs = {'name': name}
        decl_overrides = prop.info.get(self.sqla_info_key, {}).copy()
        self.declarative_overrides[name] = decl_overrides.copy()
        class_ = prop.mapper.class_
        if decl_overrides.pop('exclude', False):
            logger.debug(
                f'Relationship {name} skipped due to declarative overrides')
            return None

        for key in ['name', 'typ']:
            self.check_overrides(name, key, {}, decl_overrides, overrides)

        children = self._relationship_config(name, 'children', overrides,
                                             decl_overrides)
        includes = self._relationship_config(name, 'includes', overrides,
                                             decl_overrides)
        excludes = self._relationship_config(name, 'excludes', overrides,
                                             decl_overrides)
        rel_overrides = self._relationship_config(name, 'overrides', overrides,
                                                  decl_overrides)

        # Add default values for missing parameters.
        missing = []
        if prop.innerjoin:
            # Inner joined relationships imply it is mandatory
            missing = required

        kwargs['missing'] = missing

        kwargs.update(decl_overrides)
        kwargs.update(overrides)

        if children is not None:
            node_type = Mapping()
            if prop.uselist:
                # xToMany relationships.
                node_type = Sequence()
            return SchemaNode(node_type, *children, **kwargs)

        node = BriefySchemaNode(class_,
                                name=name,
                                includes=includes,
                                excludes=excludes,
                                overrides=rel_overrides,
                                missing=missing,
                                parents_=self.parents_ + [self.class_])

        if prop.uselist:
            node = SchemaNode(Sequence(), node, **kwargs)

        node.name = name
        return node
Exemple #18
0
 def schema_type():
     return Mapping(unknown='raise')
Exemple #19
0
 def schema_type(self, **kw):
     return Mapping(unknown='raise')
Exemple #20
0
 def serialize(self, node, appstruct):
     self.unknown = "ignore"
     return BaseMapping.serialize(self, node, appstruct)
Exemple #21
0
 def serialize(self, node, appstruct):
     self.unknown = "ignore"
     return BaseMapping.serialize(self, node, appstruct)
Exemple #22
0
 def deserialize(self, node, cstruct):
     self.unknown = "raise"
     return BaseMapping.deserialize(self, node, cstruct)
Exemple #23
0
 def schema_type(self, **kw):
     return Mapping(unknown='preserve')
Exemple #24
0
def mapping(name, unknown='preserve', **kw):
    return _node(Mapping(unknown=unknown), name=name, **kw)
Exemple #25
0
import colander
from colander import Mapping, SchemaNode
from deform import widget
from deform.widget import MappingWidget, SequenceWidget

registry = widget.default_resource_registry
registry.set_js_resources(
    'magicsuggest', None,
    'c2cgeoportal_admin:node_modules/magicsuggest-alpine/magicsuggest-min.js')
registry.set_css_resources(
    'magicsuggest', None,
    'c2cgeoportal_admin:node_modules/magicsuggest-alpine/magicsuggest-min.css')

# temporary workaround for https://github.com/Pylons/deform/pull/369
widget.DateTimeInputWidget._pstruct_schema = SchemaNode(  # pylint: disable=protected-access
    Mapping(),
    SchemaNode(widget._StrippedString(), name='date'),  # pylint: disable=protected-access
    SchemaNode(widget._StrippedString(), name='time'),  # pylint: disable=protected-access
    SchemaNode(widget._StrippedString(), name='date_submit', missing=''),  # pylint: disable=protected-access
    SchemaNode(widget._StrippedString(), name='time_submit', missing='')  # pylint: disable=protected-access
)


class ChildWidget(MappingWidget):

    template = 'child'

    def serialize(self, field, cstruct, **kw):
        from c2cgeoportal_commons.models.main import TreeItem
        if cstruct['treeitem_id'] == colander.null:
            kw['treeitem'] = TreeItem()
Exemple #26
0
 def deserialize(self, node, cstruct):
     self.unknown = "raise"
     return BaseMapping.deserialize(self, node, cstruct)
Exemple #27
0
 def __init__(self):
     super(ModelSchema, self).__init__(Mapping())
     # Child node for ``records`` will be added during deserialization
     self.add(DefinitionSchema(name='definition'))
     self.add(PermissionsSchema(name='permissions', missing={}))
    def get_schema_from_relationship(self, prop, overrides):
        """ Build and return a :class:`colander.SchemaNode` for a relationship.

        The mapping process will translate one-to-many and many-to-many
        relationships from SQLAlchemy into a ``Sequence`` of ``Mapping`` nodes
        in Colander, and translate one-to-one and many-to-one relationships
        into a ``Mapping`` node in Colander.  The related class involved in the
        relationship will be recursively mapped by ColanderAlchemy as part of
        this process, following the same mapping process.

        This method uses information stored in the relationship within
        the ``info`` that was passed to the relationship on creation.
        This means that ``Colander`` options can be specified
        declaratively in ``SQLAlchemy`` models using the ``info``
        argument that you can pass to
        :meth:`sqlalchemy.orm.relationship`.

        For all relationships, the settings will only be applied to the outer
        Sequence or Mapping. To customise the inner schema node, create the
        attribute ``__colanderalchemy_config__`` on the related model with a
        dict-like structure corresponding to the Colander options that should
        be customised.

        Arguments/Keywords

        prop
            A given :class:`sqlalchemy.orm.properties.RelationshipProperty`
            instance that represents the relationship being mapped.
        overrides
            A dict-like structure that consists of schema attributes to
            override imperatively. Values provides as part of :attr:`overrides`
            will take precendence over all others.  Example keys include
            ``children``, ``includes``, ``excludes``, ``overrides``.
        """

        # The name of the SchemaNode is the ColumnProperty key.
        name = prop.key
        kwargs = dict(name=name)
        declarative_overrides = prop.info.get(self.sqla_info_key, {}).copy()
        self.declarative_overrides[name] = declarative_overrides.copy()

        class_ = prop.mapper.class_

        key = 'exclude'
        if declarative_overrides.pop(key, False):
            log.debug('Relationship %s skipped due to declarative overrides',
                      name)
            return None

        if overrides.pop(key, False):
            log.debug('Relationship %s skipped due to imperative overrides',
                      name)
            return None

        for key in ['name', 'typ']:
            self.check_overrides(name, key, {}, declarative_overrides,
                                 overrides)

        key = 'children'
        imperative_children = overrides.pop(key, None)
        declarative_children = declarative_overrides.pop(key, None)
        if imperative_children is not None:
            children = imperative_children
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_children is not None:
            children = declarative_children
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            children = None

        key = 'includes'
        imperative_includes = overrides.pop(key, None)
        declarative_includes = declarative_overrides.pop(key, None)
        if imperative_includes is not None:
            includes = imperative_includes
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_includes is not None:
            includes = declarative_includes
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            includes = None

        key = 'excludes'
        imperative_excludes = overrides.pop(key, None)
        declarative_excludes = declarative_overrides.pop(key, None)

        if imperative_excludes is not None:
            excludes = imperative_excludes
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_excludes is not None:
            excludes = declarative_excludes
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            excludes = None

        key = 'overrides'
        imperative_rel_overrides = overrides.pop(key, None)
        declarative_rel_overrides = declarative_overrides.pop(key, None)

        if imperative_rel_overrides is not None:
            rel_overrides = imperative_rel_overrides
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_rel_overrides is not None:
            rel_overrides = declarative_rel_overrides
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            rel_overrides = None

        # Add default values for missing parameters.
        if prop.innerjoin:
            # Inner joined relationships imply it is mandatory
            missing = required
        else:
            # Any other join is thus optional
            missing = []
        kwargs['missing'] = missing

        kwargs.update(declarative_overrides)
        kwargs.update(overrides)

        if children is not None:
            if prop.uselist:
                # xToMany relationships.
                return SchemaNode(Sequence(), *children, **kwargs)
            else:
                # xToOne relationships.
                return SchemaNode(Mapping(), *children, **kwargs)

        if prop.uselist:
            node = SQLAlchemySchemaNode(class_,
                                        name=name,
                                        includes=includes,
                                        excludes=excludes,
                                        overrides=rel_overrides,
                                        missing=missing,
                                        parents_=self.parents_ + [self.class_])
            node = SchemaNode(Sequence(), node, **kwargs)
        else:
            kwargs['name'] = name
            kwargs['includes'] = includes
            kwargs['excludes'] = excludes
            kwargs['overrides'] = rel_overrides
            kwargs['parents_'] = self.parents_ + [self.class_]
            node = SQLAlchemySchemaNode(class_, **kwargs)

        node.name = name

        return node
Exemple #29
0
    class InheritedSchema(TestingSchema):
        foo = SchemaNode(Int(), missing=1)

    class ToBoundSchema(TestingSchema):
        foo = SchemaNode(Int(), missing=1)
        bazinga = SchemaNode(String(),
                             type='str',
                             location="body",
                             validator=deferred_validator)

    class DropSchema(MappingSchema):
        foo = SchemaNode(String(), type='str', missing=drop)
        bar = SchemaNode(String(), type='str')

    imperative_schema = SchemaNode(Mapping())
    imperative_schema.add(SchemaNode(String(), name='foo', type='str'))
    imperative_schema.add(
        SchemaNode(String(), name='bar', type='str', location="body"))
    imperative_schema.add(
        SchemaNode(String(), name='baz', type='str', location="querystring"))

    class TestingSchemaWithHeader(MappingSchema):
        foo = SchemaNode(String(), type='str')
        bar = SchemaNode(String(), type='str', location="body")
        baz = SchemaNode(String(), type='str', location="querystring")
        qux = SchemaNode(String(), type='str', location="header")

    class TestSchemas(TestCase):
        def test_colander_integration(self):
            # not specifying body should act the same way as specifying it
    def __init__(self,
                 class_,
                 includes=None,
                 excludes=None,
                 overrides=None,
                 unknown='ignore',
                 **kw):
        """ Initialise the given mapped schema according to options provided.

        Arguments/Keywords

        class\_
           An ``SQLAlchemy`` mapped class that you want a ``Colander`` schema
           to be generated for.

           To declaratively customise ``Colander`` ``SchemaNode`` options,
           add a ``__colanderalchemy_config__`` attribute to your initial
           class declaration like so::

               class MyModel(Base):
                   __colanderalchemy_config__ = {'title': 'Custom title',
                                                 'description': 'Sample'}
                   ...


        includes
           Iterable of attributes to include from the resulting schema. Using
           this option will ensure *only* the explicitly mentioned attributes
           are included and *all others* are excluded.

           ``includes`` can be included in the ``__colanderalchemy_config__``
           dict on a class to declaratively customise the resulting schema.
           Explicitly passing this option as an argument takes precedence over
           the declarative configuration.

           Incompatible with :attr:`excludes`. Default: None.
        excludes
           Iterable of attributes to exclude from the resulting schema. Using
           this option will ensure *only* the explicitly mentioned attributes
           are excluded and *all others* are included.

           ``excludes`` can be included in the ``__colanderalchemy_config__``
           dict on a class to declaratively customise the resulting schema.
           Explicitly passing this option as an argument takes precedence over
           the declarative configuration.

           Incompatible with :attr:`includes`. Default: None.
        overrides
            A dict-like structure that consists of schema attributes to
            override imperatively. Values provides as part of :attr:`overrides`
            will take precendence over all others.

           ``overrides`` can be included in the ``__colanderalchemy_config__``
           dict on a class to declaratively customise the resulting schema.
           Explicitly passing this option as an argument takes precedence over
           the declarative configuration.

           Default: None.
        unknown
           Represents the `unknown` argument passed to
           :class:`colander.Mapping`.

           The ``unknown`` argument passed to :class:`colander.Mapping`, which
           defaults to ``'ignore'``, can be set by adding an ``unknown`` key to
           the ``__colanderalchemy_config__`` dict. For example::

               class MyModel(Base):
                   __colanderalchemy_config__ = {'title': 'Custom title',
                                                 'description': 'Sample',
                                                 'unknown': 'preserve'}
                   ...

           In contrast to the other options in ``__colanderalchemy_config__``,
           the ``unknown`` option is not directly passed to
           :class:`colander.SchemaNode`. Instead, it is passed to the
           :class:`colander.Mapping` object, which itself is passed to
           :class:`colander.SchemaNode`.

           From Colander:

           ``unknown`` controls the behavior of this type when an unknown
           key is encountered in the cstruct passed to the deserialize
           method of this instance.

           Default: 'ignore'
        \*\*kw
           Represents *all* other options able to be passed to a
           :class:`colander.SchemaNode`. Keywords passed will influence the
           resulting mapped schema accordingly (for instance, passing
           ``title='My Model'`` means the returned schema will have its
           ``title`` attribute set accordingly.

           See
           http://docs.pylonsproject.org/projects/colander/en/latest/basics.html
           for more information.
        """

        self.inspector = inspect(class_)
        kwargs = kw.copy()

        # Obtain configuration specific from the mapped class
        kwargs.update(getattr(self.inspector.class_, self.ca_class_key, {}))
        declarative_includes = kwargs.pop('includes', {})
        declarative_excludes = kwargs.pop('excludes', {})
        declarative_overrides = kwargs.pop('overrides', {})
        unknown = kwargs.pop('unknown', unknown)
        parents_ = kwargs.pop('parents_', [])

        # The default type of this SchemaNode is Mapping.
        super(SQLAlchemySchemaNode, self).__init__(Mapping(unknown), **kwargs)
        self.class_ = class_
        self.parents_ = parents_
        self.includes = includes or declarative_includes
        self.excludes = excludes or declarative_excludes
        self.overrides = overrides or declarative_overrides
        self.unknown = unknown
        self.declarative_overrides = {}
        self.kwargs = kwargs or {}
        self.add_nodes(self.includes, self.excludes, self.overrides)
Exemple #31
0
    def get_schema_from_relationship(self, prop, overrides):
        """Extended for property support."""

        # The name of the SchemaNode is the ColumnProperty key.
        name = prop.key
        kwargs = dict(name=name)
        declarative_overrides = prop.info.get(self.sqla_info_key, {}).copy()
        self.declarative_overrides[name] = declarative_overrides.copy()

        class_ = prop.mapper

        if declarative_overrides.pop('exclude', False):
            log.debug('Relationship %s skipped due to declarative overrides',
                      name)
            return None

        for key in ['name', 'typ']:
            self.check_overrides(name, key, {}, declarative_overrides,
                                 overrides)

        key = 'children'
        imperative_children = overrides.pop(key, None)
        declarative_children = declarative_overrides.pop(key, None)
        if imperative_children is not None:
            children = imperative_children
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_children is not None:
            children = declarative_children
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            children = None

        key = 'includes'
        imperative_includes = overrides.pop(key, None)
        declarative_includes = declarative_overrides.pop(key, None)
        if imperative_includes is not None:
            includes = imperative_includes
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_includes is not None:
            includes = declarative_includes
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            includes = None

        # TODO: Utmost piece of garbage here.. remove this
        if not self.automatic_relationships:
            if name not in (self.includes or ()):
                log.debug("Does not construct relationship for %s unless explicitly included", name)
                return None

        if self.relationship_overrides:

            result = self.relationship_overrides(self, name, prop, class_)
            if result == TypeOverridesHandling.drop:
                return None
            elif result == TypeOverridesHandling.unknown:
                pass
            else:
                assert isinstance(result, colander.SchemaNode)
                return result

        key = 'excludes'
        imperative_excludes = overrides.pop(key, None)
        declarative_excludes = declarative_overrides.pop(key, None)

        if imperative_excludes is not None:
            excludes = imperative_excludes
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_excludes is not None:
            excludes = declarative_excludes
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            excludes = None

        # see issue #25 in ColanderAlchemy for possible patch
        if includes is None and excludes is None:
            includes = [p.key for p in inspect(class_).column_attrs]

        key = 'overrides'
        imperative_rel_overrides = overrides.pop(key, None)
        declarative_rel_overrides = declarative_overrides.pop(key, None)

        if imperative_rel_overrides is not None:
            rel_overrides = imperative_rel_overrides
            msg = 'Relationship %s: %s overridden imperatively.'
            log.debug(msg, name, key)

        elif declarative_rel_overrides is not None:
            rel_overrides = declarative_rel_overrides
            msg = 'Relationship %s: %s overridden via declarative.'
            log.debug(msg, name, key)

        else:
            rel_overrides = None

        # Add default values for missing parameters.
        if prop.innerjoin:
            # Inner joined relationships imply it is mandatory
            missing = required
        else:
            # Any other join is thus optional
            missing = []
        kwargs['missing'] = missing

        kwargs.update(declarative_overrides)
        kwargs.update(overrides)

        if children is not None:
            if prop.uselist:
                # xToMany relationships.
                return SchemaNode(Sequence(), *children, **kwargs)
            else:
                # xToOne relationships.
                return SchemaNode(Mapping(), *children, **kwargs)

        node = PropertyAwareSQLAlchemySchemaNode(class_,
                                    name=name,
                                    includes=includes,
                                    excludes=excludes,
                                    overrides=rel_overrides,
                                    missing=missing,
                                    type_overrides=self.type_overrides,
                                    relationship_overrides=self.relationship_overrides)

        if prop.uselist:
            node = SchemaNode(Sequence(), node, **kwargs)

        node.name = name

        return node
Exemple #32
0
 def schema_type():
     return Mapping(unknown='preserve')